same problem for me, anyone have a solution?
This works great, I’ve been able to work around the close button not working as expected by using a custom slider for the entity card (HACS), however when my curtains are closed it mention open in HA and when the curtains are open it mention close in HA. I’ve been searching however I’ve not been able to find a solution to set the cover positions in a cover template.
Thank you.
I have two curtains covering the same window. What is the process to link them as mentioned in step 2?
Is this via the app or changing the code in the cover ?
Has anyone been able to use to API to pull from a contact sensor in real time? i.e. instant (or near to) status updates when a door is open.
They have updated the rate limit to 10000 last month
I will receive my curtains devices in a couple of weeks and will be looking to hook them up via the API seen some examples above but also have created custom components before, if it is not already out there i might look in to creating one for Switch-bot curtains.
Wonderfull to integrate the switchbot curtains via API. There a two things i could not solve:
- Anyone succeeded in creating an automation with de switchbot? Is it done by Service? Entity’s are not possible with automation (i would like to use the Sun Trigger!)
- I have two differtent windows with two bots. How to aggregate them in code?
For those of you struggling with one of the buttons for the curtains being greyed out: I solved it. It has to do with the slider position. In Home Assistant a slide position of 100 means fully opened and a slide position of 0 is fully closed. In the SwitchBot API it’s the exact opposite: a slide position of 100 is fully closed and 0 is fully opened. The trick is quite simple: subtract the SlidePosition value you get with the API from 100. You have to do the same with setting the position: subtract the value from the slider in HA from 100 and pass the result as a parameter to the SwitchBot API.
As I noticed that the curtains do not always report 0 or 100 if they have been fully opened or closed, but e.g. 1 or 99, I also fixed that, by using an if-statement in the sensor template. Furthermore, I left out the stop_cover command, because the API doesn’t support that.
I used the templates from @gdeboos. This is what the SwitchBot part of my configuration.yaml looks like after my modifications:
# Switchbot setup
rest_command:
switchbot_device_command:
url: 'https://api.switch-bot.com/v1.0/devices/{{ deviceId }}/commands'
method: post
content_type: 'application/json'
headers:
Authorization: !secret switchbot_api
payload: '{"command": "{{ command }}","parameter": "{{ parameter }}"}'
sensor:
- platform: rest
name: 'Positie gordijnen balkon'
resource: !secret switchbot_balkon_status_url
method: GET
scan_interval: 600
headers:
Authorization: !secret switchbot_api
Content-Type: 'application/json'
value_template: >
{% if value_json.body.slidePosition > 95 %} 0
{% elif value_json.body.slidePosition < 5 %} 100
{% else %} {{100-value_json.body.slidePosition}}
{% endif %}
json_attributes_path: "$.body"
json_attributes:
- deviceId
- deviceType
- hubDeviceId
- calibrate
- group
- moving
- slidePosition
cover:
- platform: template
covers:
gordijnen_balkon:
device_class: curtain
friendly_name: "Gordijnen balkon"
unique_id: curtain.balkon
position_template: "{{states('sensor.positie_gordijnen_balkon')}}"
open_cover:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_balkon_deviceId
command: "turnOn"
close_cover:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_balkon_deviceId
command: "turnOff"
set_cover_position:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_balkon_deviceId
command: "setPosition"
parameter: "0,ff,{{100-position}}"
As you can see HA reports the position of the curtain for the balcony as 100 (fully opened), while the sensor read-out via the API for SlidePosition is 0.
Curtain fully opened, so slider position in HA at 100 (corresponding with a SwitchBot slide position of 0).
Curtains partially open (70 percent open), so both arrow buttons can be clicked/tapped upon. BTW: up is open, down is close.
Does anyone have a template for the Color Bulb?
Please
Everything i try, the curtains won’t react to the commands in home assistant. Even when i open/close the curtains with the switchbot app, it is not displayed in the history in Home assistant.
Also the meter isn’t working
don’t know what i’m doing wrong. out of idea’s.
But what i see at your pictures looks great.
Hello. I didn’t find sample codes/ automations for the Switchbot humidifier in this thread. Here is my setup if anyone is interested. I have used some of the codes here to call API and for the automations, helpers and sensors, I used @ tom_l lounge heating and cooling automations.
Paste these codes and adjust to your HA environment. Best to restart HA since there are quite a few of codes. Hope I didn’t missed anything.
configuration.yaml
rest_command:
switchbot_device_command:
url: "https://api.switch-bot.com/v1.0/devices/{{ deviceId }}/commands"
method: post
content_type: "application/json"
headers:
Authorization: !secret switchbot_api
payload: '{ "command": "{{ command }}", "parameter": "{{ parameter }}" }'
# humidifier sensors
rest:
- resource: !secret switchbot_wohumi_waterlevel_url
method: GET
headers:
Authorization: !secret switchbot_api
Content-Type: 'application/json'
scan_interval: 600 # adjust this to suite your need. There is api limit of 10,000 /per day.
sensor:
- name: SB Humidifier Lack Water
value_template: "{{ value_json.body.lackWater }}"
device_class: carbon_dioxide
- name: SB Humidifier Nebulization Efficiency
value_template: "{{ value_json.body.nebulizationEfficiency }}"
device_class: ozone
- name: SB Humidifier Temperature
value_template: "{{ value_json.body.temperature }}"
device_class: temperature
- name: SB Humidifier Humidity
value_template: "{{ value_json.body.humidity }}"
device_class: humidity
secret.yaml
switchbot_api: '2ac4f4dxxxxxxxx6a0718ec'
switchbot_wohumi_waterlevel_url: 'https://api.switch-bot.com/v1.0/devices/<devicID>/status'
switchbot_wohumi_id: '<deviceID>'
input_select.yaml
sb_humidifier_mode:
name: SB Humidifier Mode
icon: mdi:air-humidifier
options:
- 'Off'
- Auto
- Low
- Med
- High
input_number.yaml
lrh_humidity_low_set:
name: Humidity Low Set Point
icon: mdi:thermometer
initial: 30
min: 0
max: 100
step: 1
lrh_humidity_high_set:
name: Humidity High Set Point
icon: mdi:thermometer
initial: 50
min: 0
max: 100
step: 1
lrh_humidity_intensity_set:
name: Humidifier Intensity
icon: mdi:water-plus
min: 34
max: 100
step: 1
input_datetime.yaml
lrh_ac_am_on_time:
name: Humidifier AM On Time
has_time: true
initial: '05:00'
lrh_ac_am_off_time:
name: Humidifier AM Off Time
has_time: true
initial: '06:00'
lrh_ac_pm_on_time:
name: Humidifier PM On Time
has_time: true
initial: '18:30'
lrh_ac_pm_off_time:
name: Humidifier PM Off Time
has_time: true
initial: '19:00'
input_boolean.yaml
lrh_humidifier_automation_enable:
name: Humidifier Automation
icon: mdi:av-timer
initial: off
binary_sensor.yaml
lrh_humidifier_am_automation_time_active:
friendly_name: "LRH Humidifier AM Automation Time Active"
value_template: >-
{% set d = now().strftime("%Y-%m-%dT") %}
{% set tz = as_timestamp(now()) | timestamp_custom('%z') %}
{% set t = now().timestamp() %}
{% set am_start = as_timestamp(d ~ states('input_datetime.lrh_ac_am_on_time') ~ tz) %}
{% set am_end = as_timestamp(d ~ states('input_datetime.lrh_ac_am_off_time') ~ tz) %}
{{ am_start <= t <= am_end }}
lrh_humidifier_pm_automation_time_active:
friendly_name: "LRH Humidifier PM Automation Time Active"
value_template: >-
{% set d = now().strftime("%Y-%m-%dT") %}
{% set tz = as_timestamp(now()) | timestamp_custom('%z') %}
{% set t = now().timestamp() %}
{% set am_start = as_timestamp(d ~ states('input_datetime.lrh_ac_pm_on_time') ~ tz) %}
{% set am_end = as_timestamp(d ~ states('input_datetime.lrh_ac_pm_off_time') ~ tz) %}
{{ am_start <= t <= am_end }}
script.yaml
humidifier_low:
sequence:
- service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_wohumi_id
command: 'setMode'
parameter: 101
humidifier_med:
sequence:
- service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_wohumi_id
command: 'setMode'
parameter: 102
humidifier_high:
sequence:
- service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_wohumi_id
command: 'setMode'
parameter: 103
humidifier_auto:
sequence:
- service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_wohumi_id
command: 'setMode'
parameter: auto
humidifier_off:
sequence:
- service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_wohumi_id
command: 'turnOff'
parameter: default
lrh_humidity_intensity_set:
sequence:
- service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_wohumi_id
command: 'setMode'
parameter: "{{ states('input_number.lrh_humidity_intensity_set') }}"
automation.yaml
- alias: 'SB Humidifier'
initial_state: true
trigger:
platform: state
entity_id: input_select.sb_humidifier_mode
action:
- service_template: >
{% if is_state('input_select.sb_humidifier_mode', 'Low') %} script.humidifier_low
{% elif is_state('input_select.sb_humidifier_mode', 'Med') %} script.humidifier_med
{% elif is_state('input_select.sb_humidifier_mode', 'High') %} script.humidifier_high
{% elif is_state('input_select.sb_humidifier_mode', 'Auto') %} script.humidifier_auto
{% elif is_state('input_select.sb_humidifier_mode', 'Off') %} script.humidifier_off
{% endif %}
- alias: 'SB Humidifier Intensity'
initial_state: true
trigger:
platform: state
entity_id: input_number.lrh_humidity_intensity_set
condition:
- condition: template # Only if currently On
value_template: "{{ is_state('input_boolean.sb_humidifier', 'on') }}"
action:
- service: script.lrh_humidity_intensity_set
- alias: 'SB Humidifier AM Schedule'
trigger:
- platform: state
entity_id: binary_sensor.lrh_humidifier_am_automation_time_active
to: 'on'
for:
seconds: 10
condition:
- condition: template # Only if automation is enabled
value_template: "{{ is_state('input_boolean.lrh_humidifier_automation_enable', 'on') }}"
- condition: template # Only if currently Off
value_template: "{{ is_state('input_select.sb_humidifier_mode', 'Off') }}"
- condition: numeric_state
entity_id: sensor.sb_humidifier_humidity
above: input_number.lrh_humidity_low_set
below: input_number.lrh_humidity_high_set
- condition: template # Water tank not empty
value_template: "{{ is_state('sensor.sb_humidifier_lack_water', 'False') }}"
- condition: template # Someone is home
value_template: "{{ is_state('input_select.home_mode', 'Home') }}"
action:
service: input_select.select_option
data_template:
entity_id: input_select.sb_humidifier_mode
option: High
- alias: 'SB Humidifier PM Schedule'
trigger:
- platform: state
entity_id: binary_sensor.lrh_humidifier_pm_automation_time_active
to: 'on'
for:
seconds: 10
condition:
- condition: template # Only if automation is enabled
value_template: "{{ is_state('input_boolean.lrh_humidifier_automation_enable', 'on') }}"
- condition: template # Only if currently Off
value_template: "{{ is_state('input_select.sb_humidifier_mode', 'Off') }}"
- condition: numeric_state
entity_id: sensor.sb_humidifier_humidity
above: input_number.lrh_humidity_low_set
below: input_number.lrh_humidity_high_set
- condition: template # Water tank not empty
value_template: "{{ is_state('sensor.sb_humidifier_lack_water', 'False') }}"
- condition: template # Someone is home
value_template: "{{ is_state('input_select.home_mode', 'Home') }}"
action:
service: input_select.select_option
data_template:
entity_id: input_select.sb_humidifier_mode
option: High
- alias: 'SB Humidifier AM Off'
trigger:
- platform: state
entity_id: binary_sensor.lrh_humidifier_am_automation_time_active
to: 'off'
condition:
- condition: state # Only if AM automation is enabled
entity_id: automation.sb_humidifier_am_schedule
state: 'on'
- condition: template # And only if humidifier is on
value_template: '{{ states("input_select.sb_humidifier_mode") != "Off" }}'
action:
service: input_select.select_option
data_template:
entity_id: input_select.sb_humidifier_mode
option: 'Off'
- alias: 'SB Humidifier PM Off'
trigger:
- platform: state
entity_id: binary_sensor.lrh_humidifier_pm_automation_time_active
to: 'off'
condition:
- condition: state # Only if PM automation is enabled
entity_id: automation.sb_humidifier_pm_schedule
state: 'on'
- condition: template # And only if humidifier is on
value_template: '{{ states("input_select.sb_humidifier_mode") != "Off" }}'
action:
service: input_select.select_option
data_template:
entity_id: input_select.sb_humidifier_mode
option: 'Off'
This is how my lovelace looks like. Manual controls and automations are here. This is also taken from @ tom_l. I used decluttering-card. Make sure you have this installed and setup. You can do it without it, just follow what is in ui-lovelace.yaml and input the entities in lovelace.yaml below. The Humidifier Auotmation
switch is what will turn on your am/pm automations. Make sure it is in the on position.
ui-lovelace.yaml
humidifier_tpl:
card:
type: 'custom:vertical-stack-in-card'
cards:
- type: glance
title: '[[title]]'
state_color: false
show_name: false
entities:
- entity: '[[entity_1]]'
name: Humidifier
- entity: '[[entity_2]]'
name: Temperature
- entity: '[[entity_3]]'
name: Humidity
- entity: '[[entity_4]]'
name: Efficiency
- entities:
- head:
label: Automation
type: section
items:
- input_boolean.[[room]]_humidifier_automation_enable
- input_datetime.[[room]]_ac_am_on_time
- input_datetime.[[room]]_ac_am_off_time
- input_datetime.[[room]]_ac_pm_on_time
- input_datetime.[[room]]_ac_pm_off_time
- input_number.[[room]]_humidity_low_set
- input_number.[[room]]_humidity_high_set
- input_number.[[room]]_humidity_intensity_set
type: 'custom:fold-entity-row'
show_header_toggle: false
type: entities
lovelace.yaml (file inside of lovelace folder)
- type: custom:decluttering-card
template: humidifier_tpl
variables:
- title: Humidifier Controls
- room: lrh
- entity_1: input_select.sb_humidifier_mode
- entity_2: sensor.sb_humidifier_temperature
- entity_3: sensor.sb_humidifier_humidity
- entity_4: sensor.sb_humidifier_nebulization_efficiency
Thanks for the great work all. My curtains and IR hub are all working great. I actually really like the way they handled their api too. Super simple. Get a token, get your device id’s, make rest calls. Wish every company did this.
Only final issue I have is that even though I’m using device class curtain, it’s showing me the icon for shade (like roller shades, rather than curtains like gvandenhill’s pics showed. Happening to any one else? Otherwise, perfect.
Disregard this message. Turns out my phone is too ancient and it ended up cropping out half the switchbot api token for some reason. Wasted a couple hours to figure that out
So I’m trying to set up my switchbot devices, but I keep getting {“message”:“Unauthorized”} with the command:
curl -H "Authorization: API_KEY_HERE" https://api.switch-bot.com/v1.0/devices
I tried resetting my token a couple times, making sure I copied it correctly every time. Hub is connected to wifi. Switchbot app is updated. Unfortunately I get the same unauthorized message whether using windows command prompt or home assistant terminal
Based on the SwitchBotApi github, {“message”:“Unauthorized”} means: Http 401 Error. User permission is denied due to invalid token.
I’ve tried your method, but the close button is still greyed out, regardless of the position of the curtains. I copied your YAML, so I have no idea what’s wrong. Do you?
sensor:
- platform: rest
name: 'Gordijnen positie'
resource: !secret switchbot_gordijnen_status_url
method: GET
scan_interval: 60
headers:
Authorization: !secret switchbot_api
Content-Type: 'application/json'
value_template: >
{% if value_json.body.slidePosition > 90 %} 0
{% elif value_json.body.slidePosition < 10 %} 100
{% else %} {{100-value_json.body.slidePosition}}
{% endif %}
json_attributes_path: "$.body"
json_attributes:
- deviceId
- deviceType
- hubDeviceId
- calibrate
- group
- moving
- slidePosition
rest_command:
switchbot_device_command:
url: 'https://api.switch-bot.com/v1.0/devices/{{ deviceId }}/commands'
method: post
content_type: 'application/json'
headers:
Authorization: !secret switchbot_api
payload: '{"command": "{{ command }}","parameter": "{{ parameter }}"}'
cover:
- platform: template
covers:
gordijnen:
device_class: curtain
friendly_name: "Gordijnen"
unique_id: curtain.gordijnen
position_template: "{{states('sensor.positie_gordijnen')}}"
open_cover:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_gordijnen_deviceId
command: "turnOn"
close_cover:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_gordijnen_deviceId
command: "turnOff"
set_cover_position:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_gordijnen_deviceId
command: "setPosition"
parameter: "0,ff,{{100-position}}"
stop command not available in API as mentioned already by @gvandenhil, you can put back turnOff command = copy of close cover command
stop_cover:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_gordijnen_deviceId
command: "turnOff"
I’ve been using this with my switchbot curtains and I was just wondering if there is a way to integrate the battery status into the solution? I couldn’t see it on a quick scan of the API but would be really helpful to integrate the battery status into my Home Assistant monitoring…
Hi there,
thanks for the great work. I put my meters and my hub (as IR-Controller) in ha. Most things are fine, but it would be nice, if the IR-Buttons work as ha-buttons and not like switches. Could you give me a hint, how i can use the HA-Buttons?
Hi all,
I was constantly struggling with the calibration of my curtains. It only happened with Home Assistant, so I knew it had to be specifically that. I’ve been messing around with the code for a little bit and now my curtains are completely closing again. It seems that turnOn and turnOff are not working properly.
I also saw the remarks about the greyed out close arrow. Since the API only asks for every 10 minutes, the arrow will be white/clickable after 10 minutes (in my experience). That’s where the stop button comes in handy. That one will always close your curtain.
Below the code for what I’m using (based on the different templates that I got here)
# Switchbot
rest_command:
switchbot_device_command:
url: 'https://api.switch-bot.com/v1.0/devices/{{ deviceId }}/commands'
method: post
content_type: 'application/json'
headers:
Authorization: !secret switchbot_api
payload: '{"command": "{{ command }}","parameter": "{{ parameter }}"}'
sensor:
- platform: rest
name: 'Positie Woonkamer Gordijn'
resource: !secret switchbot_woonkamergordijn_status_url
method: GET
scan_interval: 600
headers:
Authorization: !secret switchbot_api
Content-Type: 'application/json'
value_template: '{{ value_json.body.slidePosition }}'
json_attributes_path: "$.body"
json_attributes:
- deviceId
- deviceType
- hubDeviceId
- calibrate
- group
- moving
- slidePosition
cover:
- platform: template
covers:
bedroom_curtains:
device_class: curtain
friendly_name: "Woonkamergordijn"
position_template: "{{ states('sensor.positie_woonkamer_gordijn') }}"
open_cover:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_woonkamergordijn_deviceId
command: "setPosition"
parameter: "0,ff,0"
close_cover:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_woonkamergordijn_deviceId
command: "setPosition"
parameter: "0,ff,100"
stop_cover:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_woonkamergordijn_deviceId
command: "setPosition"
parameter: "0,ff,100"
set_cover_position:
service: rest_command.switchbot_device_command
data:
deviceId: !secret switchbot_woonkamergordijn_deviceId
command: "setPosition"
parameter: "0,ff,{{position}}"
With warm regards,
Dennis