Govee Home Products / Dreamcolor LED strip

That is great news! It was a pain every update having to re-setup the light template. Glad they finally got around to the PR, it has been a while…

Is there any way to send these commands from home assistant?

I use shell_commands to send to my pi which has the bluez package installed.

Since it’s not on my NUC, I had to setup SSH to authenticate using the public key so it didn’t get prompted for a password.

https://www.thegeekstuff.com/2008/11/3-steps-to-perform-ssh-login-without-password-using-ssh-keygen-ssh-copy-id/

govee_blue: >-
  /usr/bin/ssh -i /config/ssh/pi_key -o 'StrictHostKeyChecking=no' <username>@<pi ip> gatttool -i hci0 -b <bluetooth mac> --char-write-req -a 0x0015 -n 3305020000ff00ffe9d900000000000000000004
2 Likes

Maybe someone can help me once again with another issue. I’ve now set up everything in the template and node red. However, when I log into my Alexa account and got successfully the cookie, node red throws the error “no csrf found” on the Alexa account and therefore it won’t work :confused: . This is the last step from stopping me controlling my govee light from HA and I can’t figure it out. Any help is appreciated.

Try to restart node red, if nothing delete and reinstall Alexa remote 2, if that still fails check the node red folder permissions, you may be on read only

Thank you, I also reinstalled node red. Still, it’s not working. I get up to one time running, where I can set up my device and my actions. If I deploy it then again, only the error will show up and it isn’t working. I am running everything on my Pi, in the containers. How do I check the permissions? Couldn’t find it up to now.

UPDATE: I seem to have to get it to work. The issue in was the setting “require_ssl: true” which sneaked into the config. Ty for the permission tip, now I can control the led via HA :slight_smile:

Was anyone able to reverse engineering the Bluetooth of this light strip?

2 Likes

Is it now already integrated into 0.105.2 or will the template be in 106? When I run Check Home Assistant configuration on the latest image I get the information that the color_template is an invalid option.

I don’t know why but for the 0.105 only the temperature part was taken into account. The color part will be probably added with the build 0.106.

Thank you for the information. Then I will prob wait until this update is available with the upgrading from 0.104 since it’s no big deal, and I am in no rush. Bad luck that it was this order, I removed the temperature part from my template and only kept the color one.

For those whom use google home, or just want a better option than alexa remote 2 having to fresh your cookies every other dang day, I changed my node-red flow to use the Assistant relay mentioned before.

This is how my new flow looks,

If you want to copy my flow here is the export code, just make sure to change everything accordingly to your setup.

[{"id":"6417e853.f90a58","type":"tab","label":"Govee Strip","disabled":false,"info":""},{"id":"b38dab15.6f7ea8","type":"server-events","z":"6417e853.f90a58","name":"Govee Light Strip","server":"60a5cb09.83c6b4","event_type":"call_service","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":100,"y":220,"wires":[["b3614dc6.0c609"]]},{"id":"b3614dc6.0c609","type":"switch","z":"6417e853.f90a58","name":"Govee Light","property":"payload.event.service_data.entity_id","propertyType":"msg","rules":[{"t":"eq","v":"light.govee_strip","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":270,"y":220,"wires":[["af7901cf.990f3"]]},{"id":"af7901cf.990f3","type":"switch","z":"6417e853.f90a58","name":"Off / On","property":"payload.event.service","propertyType":"msg","rules":[{"t":"eq","v":"turn_off","vt":"str"},{"t":"eq","v":"turn_on","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":420,"y":220,"wires":[["284ceb50.b16ef4"],["6a9957eb.61da08"]]},{"id":"6a9957eb.61da08","type":"function","z":"6417e853.f90a58","name":"Light Function","func":"if (typeof msg.payload.event.service_data.brightness != \"undefined\" && typeof msg.payload.event.service_data.hs_color != \"undefined\") {\n    var brightness = msg.payload.event.service_data.brightness;\n    var percent = ((brightness * 100) / 255);\n    \n    msg.payload.event.service_data.brightness = percent;\n\n    return [msg, msg, null, null, null];\n} if (typeof msg.payload.event.service_data.brightness != \"undefined\" && typeof msg.payload.event.service_data.rgb_color != \"undefined\") {\n    var brightness = msg.payload.event.service_data.brightness;\n    var percent = ((brightness * 100) / 255);\n    \n    msg.payload.event.service_data.brightness = percent;\n\n    return [msg, null, null, null, msg];\n} else if (typeof msg.payload.event.service_data.brightness != \"undefined\" && typeof msg.payload.event.service_data.color_temp != \"undefined\") {\n    var colors_numbers = [150, 222, 278, 361, 433];\n    var color_names = [\"Cool White\", \"Daylight\", \"White\", \"Soft White\", \"Warm White\"];\n    var color = msg.payload.event.service_data.color_temp;\n    var newmsg = {};\n\n    var brightness = msg.payload.event.service_data.brightness;\n    var percent = ((brightness * 100) / 255);\n    msg.payload.event.service_data.brightness = percent;\n    \n    if (color >= colors_numbers[0] && color < colors_numbers[1]) {\n        newmsg.payload = color_names[0];\n    } else if (color >= colors_numbers[1] && color < colors_numbers[2]) {\n        newmsg.payload = color_names[1];\n    } else if (color >= colors_numbers[2] && color < colors_numbers[3]) {\n        newmsg.payload = color_names[2];\n    }  else if (color >= colors_numbers[3] && color < colors_numbers[4]) {\n        newmsg.payload = color_names[3];\n    } else if (color >= colors_numbers[4] && color <= 500) {\n        newmsg.payload = color_names[4];\n    }\n    \n    return [msg, null, newmsg, null, null];\n} else if (typeof msg.payload.event.service_data.brightness != \"undefined\") {\n    var brightness = msg.payload.event.service_data.brightness;\n    var percent = ((brightness * 100) / 255);\n    \n    msg.payload.event.service_data.brightness = percent;\n    \n    return [msg, null, null, null, null];\n} else if (typeof msg.payload.event.service_data.hs_color != \"undefined\") {\n    return [null, msg, null, null, null];\n} else if (typeof msg.payload.event.service_data.color_temp != \"undefined\") {\n    var colors_numbers = [150, 222, 278, 361, 433];\n    var color_names = [\"Cool White\", \"Daylight\", \"White\", \"Soft White\", \"Warm White\"];\n    var color = msg.payload.event.service_data.color_temp;\n    var newmsg = Object();\n    \n    if (color >= colors_numbers[0] && color < colors_numbers[1]) {\n        newmsg.payload = color_names[0];\n    } else if (color >= colors_numbers[1] && color < colors_numbers[2]) {\n        newmsg.payload = color_names[1];\n    } else if (color >= colors_numbers[2] && color < colors_numbers[3]) {\n        newmsg.payload = color_names[2];\n    }  else if (color >= colors_numbers[3] && color < colors_numbers[4]) {\n        newmsg.payload = color_names[3];\n    } else if (color >= colors_numbers[4] && color <= 500) {\n        newmsg.payload = color_names[4];\n    }\n    \n    return [null, null, newmsg, null, null];\n}\n\n\nreturn [null, null, null, msg, null];","outputs":5,"noerr":0,"x":600,"y":280,"wires":[["21d40312.bc663c"],["ab8a5f76.da31"],["91894eac.33cee"],["4f385486.5a60bc"],["f424b9d.bcd4848"]]},{"id":"f0a449f8.0690f8","type":"color-convert","z":"6417e853.f90a58","input":"hsl","output":"css","outputType":"string","scaleInput":false,"x":970,"y":260,"wires":[["d5c1969.a7e0f68"]]},{"id":"ab8a5f76.da31","type":"change","z":"6417e853.f90a58","name":"","rules":[{"t":"set","p":"payload.hue","pt":"msg","to":"payload.event.service_data.hs_color[0]","tot":"msg"},{"t":"set","p":"payload.saturation","pt":"msg","to":"payload.event.service_data.hs_color[1]","tot":"msg"},{"t":"set","p":"payload.lightness","pt":"msg","to":"50","tot":"num"},{"t":"delete","p":"payload.event_type","pt":"msg"},{"t":"delete","p":"payload.event","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":260,"wires":[["f0a449f8.0690f8"]]},{"id":"f80b72bb.9fbb9","type":"color-convert","z":"6417e853.f90a58","input":"rgb","output":"css","outputType":"string","scaleInput":false,"x":970,"y":380,"wires":[["8aef2eaa.65224"]]},{"id":"f424b9d.bcd4848","type":"change","z":"6417e853.f90a58","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.event.service_data.rgb_color","tot":"msg"},{"t":"delete","p":"payload.event_type","pt":"msg"},{"t":"delete","p":"payload.event","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":380,"wires":[["f80b72bb.9fbb9"]]},{"id":"751cbfe2.32123","type":"http request","z":"6417e853.f90a58","name":"Send API Request","method":"POST","ret":"obj","paytoqs":false,"url":"http://192.168.1.39:3000/assistant","tls":"","persist":false,"proxy":"","authType":"","x":990,"y":220,"wires":[[]]},{"id":"21d40312.bc663c","type":"function","z":"6417e853.f90a58","name":"Set Payload","func":"var newmsg = {};\n\nnewmsg.payload = {};\nnewmsg.payload.user = \"vexilar\";\nnewmsg.payload.command = \"set bedroom to \" + Math.round(msg.payload.event.service_data.brightness) + \" brightness\";\n\nreturn newmsg;","outputs":1,"noerr":0,"x":790,"y":220,"wires":[["751cbfe2.32123"]]},{"id":"7de2bcd.8f7d444","type":"http request","z":"6417e853.f90a58","name":"Send API Request","method":"POST","ret":"obj","paytoqs":false,"url":"http://192.168.1.39:3000/assistant","tls":"","persist":false,"proxy":"","authType":"","x":1310,"y":380,"wires":[[]]},{"id":"4f385486.5a60bc","type":"function","z":"6417e853.f90a58","name":"Set Payload","func":"var newmsg = {};\n\nnewmsg.payload = {};\nnewmsg.payload.user = \"vexilar\";\nnewmsg.payload.command = \"turn on bedroom\";\n\nreturn newmsg;","outputs":1,"noerr":0,"x":790,"y":340,"wires":[["765d09a8.fc3a78"]]},{"id":"765d09a8.fc3a78","type":"http request","z":"6417e853.f90a58","name":"Send API Request","method":"POST","ret":"obj","paytoqs":false,"url":"http://192.168.1.39:3000/assistant","tls":"","persist":false,"proxy":"","authType":"","x":970,"y":340,"wires":[[]]},{"id":"284ceb50.b16ef4","type":"function","z":"6417e853.f90a58","name":"Set Payload","func":"var newmsg = {};\n\nnewmsg.payload = {};\nnewmsg.payload.user = \"vexilar\";\nnewmsg.payload.command = \"turn off bedroom\";\n\nreturn newmsg;","outputs":1,"noerr":0,"x":610,"y":140,"wires":[["6bfec4ee.5d31ec"]]},{"id":"6bfec4ee.5d31ec","type":"http request","z":"6417e853.f90a58","name":"Send API Request","method":"POST","ret":"obj","paytoqs":false,"url":"http://192.168.1.39:3000/assistant","tls":"","persist":false,"proxy":"","authType":"","x":810,"y":140,"wires":[[]]},{"id":"d5c1969.a7e0f68","type":"function","z":"6417e853.f90a58","name":"Set Payload","func":"var newmsg = {};\nconst colors = [\n    [\"darkviolet\", \"dark violet\"],\n    [\"blueviolet\", \"blue violet\"],\n    [\"darkorchid\", \"dark orchid\"],\n    [\"slateblue\", \"slate blue\"],\n    [\"slategray\", \"slate gray\"],\n    [\"lightslategray\", \"light slate gray\"],\n    [\"mediumorchid\", \"orchid\"],\n    [\"deeppink\", \"deep pink\"],\n    [\"mediumvioletred\", \"violet red\"],\n    [\"palevioletred\", \"light violet red\"],\n    [\"indianred\", \"indian red\"],\n    [\"firebrick\", \"fire brick\"],\n    [\"orangered\", \"orange red\"],\n    [\"darkorange\", \"dark orange\"],\n    [\"goldenrod\", \"goldenrod\"],\n    [\"darkkhaki\", \"dark khaki\"],\n    [\"greenyellow\", \"green yellow\"],\n    [\"chartreuse\", \"chartreuse\"],\n    [\"lawngreen\", \"lawn green\"],\n    [\"yellowgreen\", \"yellow green\"],\n    [\"limegreen\", \"lime green\"],\n    [\"olivedrab\", \"olive drab\"],\n    [\"mediumseagreen\", \"medium sea green\"],\n    [\"springgreen\", \"spring green\"],\n    [\"cadetblue\", \"cadet blue\"],\n    [\"mediumturquoise\", \"medium turquoise\"],\n    [\"deepskyblue\", \"deep sky blue\"],\n    [\"dodgerblue\", \"dodger blue\"],\n    [\"lightseagreen\", \"light sea green\"],\n    [\"steelblue\", \"steel blue\"],\n    [\"royalblue\", \"royal blue\"],\n    [\"mediumblue\", \"medium blue\"],\n    [\"slateblue\", \"slate blue\"],\n    [\"rebeccapurple\", \"rebecca purple\"],\n    [\"red\", \"red\"],\n    [\"blue\", \"blue\"],\n    [\"green\", \"green\"],\n    [\"yellow\", \"yellow\"],\n    [\"orange\", \"orange\"],\n    [\"gold\", \"gold\"],\n    [\"chocolate\", \"chocolate\"],\n    [\"gray\", \"gray\"],\n    [\"fuchsia\", \"fuchsia\"],\n    [\"crimson\", \"crimson\"],\n    [\"peru\", \"peru\"],\n    [\"lime\", \"lime\"],\n    [\"mediumspringgreen\", \"medium spring green\"],\n    [\"turquoise\", \"turquoise\"],\n    [\"aqua\", \"aqua\"]\n];\n\nvar color = colors.filter(element => element[0] === msg.payload);\nnewmsg.payload = {};\nnewmsg.payload.user = \"vexilar\";\nnewmsg.payload.command = \"set bedroom to \" + color[0][1];\n\nreturn newmsg;","outputs":1,"noerr":0,"x":1130,"y":260,"wires":[["91be7fd8.809ec"]]},{"id":"91be7fd8.809ec","type":"http request","z":"6417e853.f90a58","name":"Send API Request","method":"POST","ret":"obj","paytoqs":false,"url":"http://192.168.1.39:3000/assistant","tls":"","persist":false,"proxy":"","authType":"","x":1310,"y":260,"wires":[[]]},{"id":"91894eac.33cee","type":"function","z":"6417e853.f90a58","name":"Set Payload","func":"var newmsg = {};\n\nnewmsg.payload = {};\nnewmsg.payload.user = \"vexilar\";\nnewmsg.payload.command = \"set bedroom to \" + msg.payload;\n\nreturn newmsg;","outputs":1,"noerr":0,"x":790,"y":300,"wires":[["490d2d0d.db7654"]]},{"id":"490d2d0d.db7654","type":"http request","z":"6417e853.f90a58","name":"Send API Request","method":"POST","ret":"obj","paytoqs":false,"url":"http://192.168.1.39:3000/assistant","tls":"","persist":false,"proxy":"","authType":"","x":970,"y":300,"wires":[[]]},{"id":"8aef2eaa.65224","type":"function","z":"6417e853.f90a58","name":"Set Payload","func":"var newmsg = {};\nconst colors = [\n    [\"darkviolet\", \"dark violet\"],\n    [\"blueviolet\", \"blue violet\"],\n    [\"darkorchid\", \"dark orchid\"],\n    [\"slateblue\", \"slate blue\"],\n    [\"slategray\", \"slate gray\"],\n    [\"lightslategray\", \"light slate gray\"],\n    [\"mediumorchid\", \"orchid\"],\n    [\"deeppink\", \"deep pink\"],\n    [\"mediumvioletred\", \"violet red\"],\n    [\"palevioletred\", \"light violet red\"],\n    [\"indianred\", \"indian red\"],\n    [\"firebrick\", \"fire brick\"],\n    [\"orangered\", \"orange red\"],\n    [\"darkorange\", \"dark orange\"],\n    [\"goldenrod\", \"goldenrod\"],\n    [\"darkkhaki\", \"dark khaki\"],\n    [\"greenyellow\", \"green yellow\"],\n    [\"chartreuse\", \"chartreuse\"],\n    [\"lawngreen\", \"lawn green\"],\n    [\"yellowgreen\", \"yellow green\"],\n    [\"limegreen\", \"lime green\"],\n    [\"olivedrab\", \"olive drab\"],\n    [\"mediumseagreen\", \"medium sea green\"],\n    [\"springgreen\", \"spring green\"],\n    [\"cadetblue\", \"cadet blue\"],\n    [\"mediumturquoise\", \"medium turquoise\"],\n    [\"deepskyblue\", \"deep sky blue\"],\n    [\"dodgerblue\", \"dodger blue\"],\n    [\"lightseagreen\", \"light sea green\"],\n    [\"steelblue\", \"steel blue\"],\n    [\"royalblue\", \"royal blue\"],\n    [\"mediumblue\", \"medium blue\"],\n    [\"slateblue\", \"slate blue\"],\n    [\"rebeccapurple\", \"rebecca purple\"],\n    [\"red\", \"red\"],\n    [\"blue\", \"blue\"],\n    [\"green\", \"green\"],\n    [\"yellow\", \"yellow\"],\n    [\"orange\", \"orange\"],\n    [\"gold\", \"gold\"],\n    [\"chocolate\", \"chocolate\"],\n    [\"gray\", \"gray\"],\n    [\"fuchsia\", \"fuchsia\"],\n    [\"crimson\", \"crimson\"],\n    [\"peru\", \"peru\"],\n    [\"lime\", \"lime\"],\n    [\"mediumspringgreen\", \"medium spring green\"],\n    [\"turquoise\", \"turquoise\"],\n    [\"aqua\", \"aqua\"]\n];\n\nvar color = colors.filter(element => element[0] === msg.payload);\nnewmsg.payload = {};\nnewmsg.payload.user = \"vexilar\";\nnewmsg.payload.command = \"set bedroom to \" + color[0][1];\n\nreturn newmsg;","outputs":1,"noerr":0,"x":1130,"y":380,"wires":[["7de2bcd.8f7d444"]]},{"id":"60a5cb09.83c6b4","type":"server","z":"","name":"Home Assistant","legacy":false,"hassio":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]
2 Likes

Thank you for posting this! I know it’s a little old now, but could you please elaborate on step 5? How/Where do I go about creating a rest command inside HA? Sorry for the ignorant question, I’m new to HA and trying to get my bearings.

Update, I got the rest_command added (it’s just an addition to the configuration.yaml, in case someone else reads this and gets stuck where I did).

I can run the command “turn on lights” in the Assistant Relay Web UI, but when I try to do it through that rest_command, nothing seems to happen. I’ve copied your code exactly for that command, except I swapped the URL for http://homeassistant.local:3000/assistant and I put in my email address.

Update: I now see “Error. Url: http://homeassistant.local:3000/assistant. Status code 500.” in my logs, although that doesn’t seem super helpful

Second Update: I got it working! In case anyone else runs into the same issues I have, here are a few things to note (some seem obvious, but weren’t to me)

  1. The assistant_relay_command code goes nested under a rest_command in your configuration.yaml
  2. In that command, you don’t necessarily have to use your email. It wasn’t working for me so I tried changing it to the username I had in Assistant Relay (in this case, my name) and that made it work)
  3. The switch code he posted goes nested under a switch in your configuration.yaml. This may be really obvious to most, but silly me put it under a light, since in my mind I was configuring a light.
2 Likes

Hi there,

I am currently working on a Govee client (IOT/TCP plus Bluetooth) written in Python. In case a device supports IOT, we will do so. Otherwise, the client communicates with the devices via Bluetooth.
You can find the first version here: https://github.com/thomasreiser/govee_api/

At the moment, I can only confirm support for H6159, H6163, H6113 (LED strips) and H6001 (Bulb)

It would be great if you could confirm if your devices also work with the client, and if not, it would be great if you would provide me with the raw data received from Govee (can be extracted/printed out in the example test client) or if you send me a pull request.

If someone wants to create a HA plugin - feel free to do so!

[EDIT: Changed list of supported devices + added info about newly added Bluetooth support]

[EDIT: Repository was shut down on behalf of Govee. They say they are working on a official public API at the moment]

4 Likes

Hi @Vexlar, I’m quite new to HA and have recently got some Govee lights, they are connected to my Echo/Alexa and I’m struggling to get them to work with HA.

I’ve installed node-red and alexa remote2, do you have any further instructions on how to set this up? I appreciate your time. Thanks

EDIT: I’ve managed to get this working. Thanks! I can control the lights on/off, colour and brightness.
Now to my hue dimmer to control the lights…

I’m in the same boat you were in, I can control the light via the Assistant Relay interface, but home assistant is throwing a 500:

2020-06-29 15:34:40 INFO (MainThread) [homeassistant.helpers.script] Running script
2020-06-29 15:34:40 INFO (MainThread) [homeassistant.helpers.script] Executing step call service
2020-06-29 15:34:40 WARNING (MainThread) [homeassistant.components.rest_command] Error. Url: http://192.168.1.200:3000/assistant. Status code 500.
2020-06-29 15:34:40 WARNING (MainThread) [homeassistant.helpers.service] Unable to find referenced entities input_boolean.salon_tv_ambient_light

This works:

Relevant YAML in my config:

salon_tv_ambient_light:
        value_template: '{{ states("input_boolean.salon_tv_ambient_light") }}'
        friendly_name: 'TV ambient light'
        turn_on:
           -  service: rest_command.assistant_relay_command
              data:
                 command: "turn on Bedroom LED"
           -  service: input_boolean.turn_on
              entity_id: input_boolean.salon_tv_ambient_light
        turn_off:
           -  service: rest_command.assistant_relay_command
              data:
                 command: "turn off Bedroom LED"
           -  service: input_boolean.turn_off
              entity_id: input_boolean.salon_tv_ambient_light


rest_command:
   assistant_relay_command:
      url: http://192.168.1.200:3000/assistant
      method: POST
      content_type: 'application/json'
      payload: '{"command":"{{ command }}", "user":"[HomeAssistant]"}'

If you have any suggestions on how to fix the 500 I’d love to hear them. :slight_smile:

EDIT: I’m an idiot, the brackets on either side of the user “HomeAssistant” had to come out.

fixed syntax:

rest_command:
   assistant_relay_command:
     url: http://192.168.1.200:3000/assistant
     method: POST
     content_type: 'application/json'
     payload: '{"command":"{{ command }}", "user":"HomeAssistant"}'

The only bummer is it doesn’t sync the state as someone else mentioned, so you kind of have to flip it on then off to actually turn it off. Still better than nothing until Govee releases their public API.

Thank you so much @Vexlar, this is really fantastic work. I’ve never used Node Red before but I took your template, did a find/replace on the things that made sense (Vexlar, set bedroom to, etc.) and it works!!!

I am running home assistant on a docker container , any idea on how I can implement this as I don’t use hass.io ?

Just got an email from Govee that mentions an API. Does this mean we can finally integrate directly into HA?

Dear User,

The Govee Home app v3.5.0 is now available, update yours to explore exciting features!

Whats New:

· Updated APIs
Program the app to make it best suit your needs.
2 Likes

Woo hoo, got a DM on the Twitter machine from govee that public api will be available within 48hrs (and to follow them on Twitter for details). Not that I can do anything with this info, but one of you can!!! :smiley:

2 Likes

Hi @bowhunt24,

Have you had anything further from Govee? Can’t see anything on their twitter about an API :frowning:

Thanks,
Adam