Switchbot Light Strip through API

Hi everyone,

I am trying to integrate Swichbot LS using the API. “Turn on”, “Turn off” and “Brightness” commands are working. Now I am trying to change colors.

HA documentation says “rgb_color” should return a tuple: Return the rgb color value (int, int, int)
SwitchBot API is expecting: "{0-255}:{0-255}:{0-255}"

I tried almost everything: regex replacement, spliting R G B… nothing worked or my code wasn’t good.

It would be nice if anybody could help me. Thank you very much !

My code is available on Github: GitHub - LittleJ/HomeAssistant-Switchbot-API: Connect Home Assistant to Switchbot API

Still trying things with no success.

In DEV > State, it says the light supports HS. I try to change this to RGB. I tried many things, not sure what I am doing anymore…

I need HA to understand the light is RGB and i need to get the R-G-B values separately… Anyone to help ? Thanks !

Forgive me if this doesn’t help, but I think it might.

Im not sure if you found a solution but having recently solved this, here is my setup. This is working in HASS v2023.1.7

configuration.yaml

sensor to recieve the json from the API.

sensor:
#other sensors
  - platform: command_line
    name: 'Bedroom - Strip Light'
    scan_interval: 30
    command_timeout: 30
    command: !secret SwitchbotLightCmd
    value_template: '{{ value_json }}'
    json_attributes:
      - power
      - brightness
      - color


rest_command to accept the data to be sent.

rest_command:
  switchbot_device_command:
    url: 'https://api.switch-bot.com/v1.0/devices/{{ deviceId }}/commands'
    method: post
    headers:
      Authorization: !secret SwitchbotAPI
      Content-Type: 'application/json'
    payload: '{"command":"{{ command }}","parameter":"{{ parameter }}","commandType":"{{ commandType }}"}'


light template.

light:
  - platform: template
    lights:
      bedroom_strip_light:
        friendly_name: "Bedroom - Strip Light"
        unique_id: light.bedroom_strip_light
        icon_template: mdi:led-strip-variant
        level_template: "{{ state_attr('sensor.bedroom_strip_light', 'brightness') | int }}"
        color_template: "{{ states('input_text.bedroom_strip_hs').split(',')[0] | int}},{{ states('input_text.bedroom_strip_hs').split(',')[1] | int }}"
        value_template: "{{ state_attr('sensor.bedroom_strip_light', 'power') }}"
        turn_on:
          service: rest_command.switchbot_device_command
          data:
            deviceId: !secret SwitchbotLightId
            command: "turnOn"
            parameter: "default"
            commandType: "command"
        turn_off: 
          service: rest_command.switchbot_device_command
          data:
            deviceId: !secret SwitchbotLightId
            command: "turnOff"
            parameter: "default"
            commandType: "command"
        set_level:
          service: rest_command.switchbot_device_command
          data:
            deviceId: !secret SwitchbotLightId
            command: "setBrightness"
            parameter: "{{brightness}}"
            commandType: "command"
        set_color:
          - service: input_text.set_value
            target:
              entity_id: input_text.bedroom_strip_hs
            data:
              value: "{{ h }},{{ s }},70"
          - service: script.hs_to_rgb
            data:
              service_id: bedroom_strip_set_color
              h: "{{ h }}"
              s: "{{ s }}"
              l: 70

note: the “l” value at the end. Although not needed for the light the conversion script I made is general purpose and in theory could be used for other things too.

secrets.yaml

SwitchbotAPI: <your_api_key_here>
SwitchbotLightId: <your_device_id_here>
SwitchbotLightCmd: "curl -H 'Authorization: <your_api_key_here> -H 'Accept: appication/JSON' https://api.switch-bot.com/v1.0/devices/<your_device_id_here>/status | jq '.body'"

Helpers

input_text.bedroom_strip_hs

I set this up in the UI but its easy enough to set in yaml.

Automation

alias: Bedroom - Strip RGB to HS
description: Converts lights RGB value to HS for use in bedroom strip sensor.
trigger:
  - platform: state
    entity_id:
      - sensor.bedroom_strip_light
condition: []
action:
  - service: script.rgb_to_hs
    data:
      inputName: bedroom_strip_hs
      r: "{{state_attr('sensor.bedroom_strip_light','color').split(':')[0] }}"
      g: "{{state_attr('sensor.bedroom_strip_light','color').split(':')[1] }}"
      b: "{{state_attr('sensor.bedroom_strip_light','color').split(':')[2] }}"
mode: single

When the sensor update it sends the data to the script.rgb_to_hs for conversion.

Scripts

hs_to_rgb converter.
alias: RGB to HS
sequence:
  - service: input_text.set_value
    target:
      entity_id: input_text.{{inputName}}
    data:
      value: |-
        {% set r_dec = (r | int)/255 %}
        {% set g_dec = (g | int)/255 %} 
        {% set b_dec = (b | int)/255 %}
        {% set rgb_decimal = r_dec,g_dec,b_dec %}

        {% set maxc = rgb_decimal | max %} 
        {% set minc = rgb_decimal | min %} 
        {% set l_dec = (maxc + minc) / 2 %} 
        {% set l = (l_dec * 100) | int %}

        {% if maxc == minc %}  
          {% set s_dec = 0 %}
        {% elif l_dec <= 0.5 %}
          {% set s_dec = (maxc - minc) / (maxc + minc + 0.001) %}
        {% else %}
          {% set s_dec = (maxc - minc) / (2.0 - maxc - minc) %}
        {% endif %}

        {% set s = (s_dec * 100) | int %} 
        {% if r_dec == maxc %}
          {% set h_deg = ((g_dec - b_dec) / (maxc - minc + 0.001)) * 60 %}
        {% elif g_dec == maxc %}
          {% set h_deg = ((2.0 + (b_dec - r_dec)) / (maxc - minc + 0.001)) * 60 %}
        {% else %}
          {% set h_deg = ((4.0 + (r_dec - g_dec)) / (maxc - minc + 0.001)) * 60 %}
        {% endif %}

        {% if h_deg < 0 %}
          {% set h = h_deg + 360 %}
        {% elif h_deg > 360 %}
          {% set h = h_deg - 360 %}
        {% else %}
          {% set h = h_deg %}
        {% endif %}

        {{ h | round(0)}},{{ s | round(0)}},{{ l | round(0) }}
mode: single
icon: mdi:palette

This script is set up in a way that it can be used for other sensors too.

hs_to_rgb converter

service: script.turn_on
target:
  entity_id: script.{{ service_id }}
data:
  variables:
    rgb_color: >-
      {% set h_dec = h/360 %} {% set s_dec = s/100 %}  {% set l_dec = l/100 %}
      {% if l_dec < 0.5 %} 
        {% set temp1 = l_dec * (s_dec + 1) %} 
      {% elif l_dec >= 0.5 %}
        {% set temp1 = l_dec + s_dec - (l_dec * s_dec) %}
      {% endif %} {% set temp2 = (2 * l_dec) - temp1 %} {% if h_dec + 0.333 >
      1%}
        {% set r_temp = h_dec - 0.667 %}
      {% else %}
        {% set r_temp = h_dec + 0.333 %}
      {% endif %}
        {% set g_temp = h_dec %}
      {% if h_dec - 0.333 < 0 %}
        {% set b_temp = h_dec + 0.667 %}
      {% else %}
        {% set b_temp = h_dec - 0.333 %}
      {% endif %} {% if s == 0 %} 
        {% set r = (l_dec*255) | round(0) %}
        {% set g = (l_dec*255) | round(0) %}
        {% set b = (l_dec*255) | round(0) %} 
      {% else %}
        {% if r_temp * 6 < 1 %}
          {% set r = ((temp2 + (temp1 - temp2) * 6 * r_temp) * 255) | round(0) %}
        {% elif r_temp * 2 < 1 %}
          {% set r = (temp1 * 255) | round(0) %}
        {% elif r_temp * 3 < 2 %}
          {% set r = ((temp2 + (temp1 - temp2) * (0.666 * r_temp) * 6) * 255) | round(0) %}
        {% else %} 
          {% set r = (temp2 * 255) | round(0) %} 
        {% endif %} 

        {% if g_temp * 6 < 1 %}
          {% set g = ((temp2 + (temp1 - temp2) * 6 * g_temp) * 255) | round(0) %}
        {% elif g_temp * 2 < 1 %}
          {% set g = (temp1 * 255) | round(0) %}
        {% elif g_temp * 3 < 2 %}
          {% set g = ((temp2 + (temp1 - temp2) * (0.666 * g_temp) * 6) * 255) | round(0) %} 
        {% else %}
          {% set g = (temp2 * 255) | round(0) %}
        {% endif %}

        {% if b_temp * 6 < 1 %} 
          {% set b = ((temp2 + (temp1 - temp2) * 6 * b_temp) * 255) | round(0) %}
        {% elif b_temp * 2 < 1 %}
          {% set b = (temp1 * 255) | round(0) %}
        {% elif b_temp * 3 < 2 %} 
          {% set b = ((temp2 + (temp1 - temp2) * (0.666 * b_temp) * 6) * 255) | round(0) %}
        {% else %}
          {% set b = (temp2 * 255) | round(0) %} 
        {% endif %}
      {% endif %}    {{ r }},{{ g }},{{ b }}

This script is for converting the hs color from Home Assistant back into rgb for switchbot.

script.bedroom_strip_set_color finally send the obtained rgb colors to the rest_command.

alias: Bedroom - Strip - Set Color
sequence:
  - service: rest_command.switchbot_device_command
    data:
      deviceId: <you_device_id_here>
      command: setColor
      parameter: "{{rgb_color[0]}}:{{rgb_color[1]}}:{{rgb_color[2]}}"
      commandType: command
mode: single
icon: mdi:palette

Dont forget to put you deviceId into this script. Scripts dont play nice with !secret.


Final Notes

  • If you click too quickly on a new color or make too frequent requests you may get empty json errors in logs.
  • If the sensor updates at the same time as a color is selected the picker will revert to the old color until the next refresh.

There are probably other ways of doing this but this worked for me. I hope this helps somebody.