Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FYI: Computing Scene Codes #11

Open
wez opened this issue Dec 31, 2023 · 38 comments
Open

FYI: Computing Scene Codes #11

wez opened this issue Dec 31, 2023 · 38 comments
Labels
Enhancement New information regarding a product

Comments

@wez
Copy link

wez commented Dec 31, 2023

I've been poking at things and found something that I think you may find useful, and may be worth documenting here.

You can download a catalog of pre-defined scenes for a given sku; you need to pass the AppVersion header for it to return anything:

$ curl "https://app2.govee.com/appsku/v1/light-effect-libraries?sku=H6072" -H 'AppVersion: 5.6.01' -s

Which produces data like the following abbreviated excerpt:

{
  "message": "success",
  "status": 200,
  "data": {
    "categories": [
{
  "sceneId": 7691,
  "iconUrls": [
    "https://d1f2504ijhdyjw.cloudfront.net/deals-img/c1068ace12a82ee32333f5c35bbc154e-new_light_btn_scenes_four_color%403x.png",
    "https://d1f2504ijhdyjw.cloudfront.net/deals-img/9215bf8e3df86bd03eb32b93fd3f5b3b-new_light_btn_scenes_four_color_press%403x.png",
    "https://d1f2504ijhdyjw.cloudfront.net/deals-img/6b7e891d014ba5742fbbc02368e077e9-new_light_btn_scenes_four_color_dark%403x.png"
  ],
  "sceneName": "rainbow B",
  "analyticName": "rainbow B",
  "sceneType": 2,
  "sceneCode": 0,
  "scenceCategoryId": 0,
  "popUpPrompt": 0,
  "scenesHint": "",
  "rule": {
    "maxSoftVersion": "",
    "minSoftVersion": "",
    "maxHardVersion": "",
    "minHardVersion": "",
    "maxWifiSoftVersion": "",
    "minWifiSoftVersion": "",
    "maxWifiHardVersion": "",
    "minWifiHardVersion": ""
  },
  "lightEffects": [
    {
      "scenceParamId": 11837,
      "scenceName": "",
      "scenceParam": "ASkAAAAHAgH/gQD5FBQD+RQG/wAA/38A//8AAP8AAP//AAD/EADyAACAAA==",
      "sceneCode": 10191,
      "specialEffect": [],
      "cmdVersion": 1,
      "sceneType": 2,
      "diyEffectCode": [],
      "diyEffectStr": "",
      "rules": [],
      "speedInfo": {
        "config": "",
        "speedIndex": 0,
        "supSpeed": false
      }
    }
  ],
  "voiceUrl": "",
  "createTime": 0
},

],
"supportSpeed": 1
  }
}

The part of interest is the sceneCode in the lightEffects list; for the Rainbow above, ignore its direct sceneCode: 0 and look inside its lightEffects list for its sceneCode: 10191

Using some jq, we can produce a simpler list:

$ curl "https://app2.govee.com/appsku/v1/light-effect-libraries?sku=H6072" -H 'AppVersion: 5.6.01' -s | \
   jq '[.data.categories[].scenes[] | {name: .sceneName, code: .lightEffects[0].sceneCode}]'

outputs something like this excerpt:

[
  {
    "name": "Sunrise",
    "code": 2099
  },
  {
    "name": "rainbow B",
    "code": 10191
  },
]

Armed with that you can now construct a BLE packet that will activate a scene if you know its name. Taking that rainbow B example, its scene code is 10191 in decimal. Convert to hex to produce: 0x27cf which you can break into two bytes and swap around, adding on to a scene mode packet, similar to the others discussed in this repo:

0x33 0x05 0x04 0xcf 0x27

then zero-pad out to 19 bytes + checksum and voila, you have a packet that you can send either via BLE or via the LAN ptReal command that will activate that scene.

I figured this out by following https://github.com/bwp91/homebridge-govee/wiki/Scene%2C-Music%2C-DIY-Modes which suggests saving a short-cut for a scene in the govee app, and then plucks the corresponding base64 encoded version of the packet out of some data returned from another govee URL.

$ echo MwUEzycAAAAAAAAAAAAAAAAAANo= | base64 -d | xxd
00000000: 3305 04cf 2700 0000 0000 0000 0000 0000  3...'...........
00000010: 0000 00da                                ....

Staring at some other data from the new HTTP platform API that returns scene codes (https://developer.govee.com/reference/get-light-scene), I realized that the code was embedded in that packet.

LAN Protocol and ptReal

The Govee LAN Protocol doesn't document this, but you can send BLE packets to the device via the LAN protocol by encoding them as base64 packets and sending data like this to UDP port 4003 on the target device:

{
  "msg":{
    "cmd":"ptReal",
    "data":{
      "command": ["MwUEzycAAAAAAAAAAAAAAAAAANo="]
    }
  }
}
$ echo '{"msg":{"cmd":"ptReal","data":{"command":["MwUEzycAAAAAAAAAAAAAAAAAANo="]}}}' | \
    nc -u 192.168.1.100 4003
@jstnkndll
Copy link

Very Useful Thank You, for taking the time to document this and explain this.

@wez
Copy link
Author

wez commented Jan 12, 2024

FWIW, it doesn't seem to work reliably for scene codes larger than 0xff, so this isn't 100%, but it does give a way to map from the list of known codes to data you can send to the device.

@egold555
Copy link
Owner

This is awesome, thanks for this documentation!

Unsure if you think we should leave this as a open issue (Maybe we pin it) or is it worth adding a file / folder for documentation like this to the repo?

I am open to any and all ideas

@egold555 egold555 added the Enhancement New information regarding a product label May 15, 2024
@loebi-ch
Copy link

Hi @wez!

Yesterday I've got some Govee Floor Lamps Basic on my birthday and wanted to integrate them into my Home Assistant. Unfortunately it didn't work as easy as I expected. These are my first Govee devices. I encountered your name and your posts at different places and obviousley you're the man that knows the most about the propriatary Govee solutions. I integrated the lamps into HA with different addons and I also tried your Govee2MQTT addon which runs quite well, but faces some problems when it comes to setting colors onto single segments. Mainly it works, but since it's using the cloud, the reaction time is very bad, when setting segments 0..7 one by one. I'm a programmer and I quickly setup my own UDP server to check the local LAN API. It was no problem to discover the lamps and setting color and brightness, but no word about setting single segments in the manual. I nearly gave up and then discovered this post and the "ptReal" command. But I didn't get how to discover the payload for this command.

You write Convert to hex to produce: 0x27cf which you can break into two bytes and swap around, adding on to a scene mode packet, similar to the others discussed in this repo
I understand how to find the appropriate scene code, but wrapping the hex code of this scene code around WHAT? How do I build the correct scene mode packet and calculate the checksum? Can you give me some hints?

My intention actually is to use my Govee Floor Lamps not with the predefined scenes, but just some static gradients. I don't like the animations. Maybe for a party, but in my everyday life I just want the lamps to shine in different static gradients. Do you think this will be possible localy without using the Govee app? Will these be anyhow possible with the LAN API?

Besides, thank you very much for all your efforts that you are putting in for the community!

Best regards
Andy

@egold555 egold555 pinned this issue May 22, 2024
@Hauty9
Copy link

Hauty9 commented Nov 5, 2024

Hello @wez !

I have the same question as @loebi-ch about how to calculate the scene code. Are you able to give us a step by step of what you mean when you say:

Convert to hex to produce: 0x27cf which you can break into two bytes and swap around, adding on to a scene mode packet then zero-pad out to 19 bytes + checksum.

I understand how to convert decimal to hex but get lost when you say to break into two bytes and swap around. I also do not understand the zero-pad out to 19bytes + checksum.

I would love to use this for my Govee permanent lights via the LAN API which has very little control to it.

Please let me know if you can give further instructions on how to calculate the scene codes.

Thanks!

Braden

@AlgoClaw
Copy link

AlgoClaw commented Nov 14, 2024

@Hauty9 Here are notes I took when I figured this out. Hope it helps.

Using the example of the scene "Forest"

Scene = Forest
Cloud API = 130
Offset = Cloud API - 128 = 2
Hex Offset = hex(Offset) = 0002
Hex Scene Prefix = 33 05 04
Hex Command = Hex Scene Prefix + Hex Offset(3,2) + Hex Offset(1,2) = 33 05 04 02 00
Checksum = XORchecksum(Hex Command) = 30
Pad = 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Combined = Hex Command + Pad + Checksum = 33 05 04 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30
Combined_No_Space = 3305040200000000000000000000000000000030
BT Command = base64(Combined_No_Space) = MwUEAgAAAAAAAAAAAAAAAAAAADA=

At the step "Hex command", you take the offset (0002), break it into 2 parts (00) and (02), then switch them around (0200). I think that is the part you are stuck at.

Calculate the XORChecksum of "Hex Command" here: https://tinkererway.dev/the_dev_calc/xor_crc_calc https://www.scadacore.com/tools/programming-calculators/online-checksum-calculator/

Calculate the base64 of the hex "Combined_No_Space" here: https://base64.guru/converter/encode/hex

@Hauty9
Copy link

Hauty9 commented Nov 16, 2024

@AlgoClaw Thanks for the explanation, however I think I'm still a bit lost on some parts.

Where do you get the Hex Scene Prefix from? Does this number change per scene or is it always the same.

For the Cloud API, is the number the scene ID or ParamID?

I'm pulling the scene information my Govee permanent outdoor lights.

My "forest" scene has an id of 10745 and ParamID of 17950

Thank you for your help!

@AlgoClaw
Copy link

AlgoClaw commented Nov 18, 2024

@Hauty9

  1. The scene prefix code is the same for any "scene". There are different prefixes if you are setting the mode to "color", "music", "DIY", etc. I have no idea what those other prefixes are. But, if you are setting a predefined "scene", the scene code prefix is always "33 05 04". That is my understanding, at least.

  2. Ehh, for the cloud API, I don't really remember... I don't think it ever lined up properly. My use of the term "cloud API" may not be correct (sorry). I was grabbing the number by pulling the data from Govee.

I have several H61A8, so I can pull the data using:

`curl "https://app2.govee.com/appsku/v1/light-effect-libraries?sku=H61A8" -H 'AppVersion: 5.9.20' -s > govee_H61A8.json'

or, if you want to filter for just the "sceneName" and "sceneId", use:

'curl "https://app2.govee.com/appsku/v1/light-effect-libraries?sku=H61A8" -H 'AppVersion: 5.9.20' -s | jq '[.data.categories[].scenes[] | {name: .sceneName, sceneId: .sceneId}]' > govee_H61A8_scenes.json'

For the H61A8, the "Forest" scene has "sceneId" 130, and dozens of different "scenceParamId". I think sceneId is the critical one. If I remember correctly, the scene codes only translated properly a few times. If you figure that part out, please post here to let me (and everyone else) know.

I was keeping track of my H61A8 stuff here (https://docs.google.com/spreadsheets/d/1FokCgrgi34qqEEiy1-_AeeroNMDFz-83XSapXxNVXFI/edit?usp=sharing), but I got bored and moved on after a while.

Post the model number of your lights and I can pull the data for it and see if I can help.

@Hauty9
Copy link

Hauty9 commented Nov 18, 2024

@AlgoClaw

Thank you for all the explanations! I used postman to pull the information about the scenes from Govee. I did:
POST https://openapi.api.govee.com/router/api/v1/device/scenes
{
"requestId": "uuid",
"payload": {
"sku": "H805A",
"device": "Device_ID"
}
}

That returned all the scene information for my lights. For mine, the "forest" scene returns like this:
{
"name": "Forest",
"value": {
"id": 10745,
"paramId": 17950
}

However, Any of my DIY Scenes come back with a a 8 number value and not an ID or paramId.

I have the Permanent Outdoor Elite series. H805A

Do all your scenes only have a 3 number value?

Thanks!

@AlgoClaw
Copy link

@Hauty9

Do all your scenes only have a 3 number value?

Most have 3 digits, but not all. A dozen-or-so have 4 and 5 digits. For example, the newly added "Thanksgiving" has sceneId 15332. Other examples "Dreamlike":7610 "Undersea King":8400 "ARRAKIS":10067.

my DIY Scenes come back with a 8 number value and not an ID or paramId.

How are you getting info for DIY scenes? The public API should not have anything specific to your setup. Also note, "DIY" scenes may have a different prefix.

We are nearing the end of my knowledge about this stuff. Most of what I know is from reading @wez 's comments and posts on the subject and then a little trial-and-error from trying to do it myself.


At this point, you are probably just going to have to go through each number individually to see what the output is. For H61A8, only "Sunrise", "Sunset", and "Forest" worked as expected. The 100+ I tried after did not line up.

Govee is not making it easy. The "WLAN Guide" they released provides only top-level generic information (https://app-h5.govee.com/user-manual/wlan-guide). However, I was playing in the app last night and found some additional stuff that might bring insight.

It seems "Razer Chroma" is now able to control Govee lights through LAN communication. If you go to -- Govee app > "Home" tab > human silhouette in bottom-right > "Local Services" -- it will open a "User Guide" for how to interact with Razer Chroma. It also certainly uses LAN connections, as the guide specifies that the "LAN Control" option must be enabled for each device and Razer Chroma must be running on the same network.

I have no idea what Razer Chroma is, but this may provide a much easier way to interact.

@Hauty9
Copy link

Hauty9 commented Dec 3, 2024

@AlgoClaw

This is all very interesting. I use Postman to pull all the scenes from the API. The POST command looks like this:

https://openapi.api.govee.com/router/api/v1/device/scenes

In the body of my POST command is:
{
"requestId": "uuid",
"payload": {
"sku": "H805A",
"device": "Device ID I found in the Govee App"
}
}

That POST request will return all the scene information.
I have yet to see a scene ID with less than 5 digits. I am able to trigger these scenes via the cloud API with the 5 digit ID and paraID but would rather have the control be local

My Thanksgiving scene outputs like this:

"name": "Thanksgiving",
"value": {
"id": 10775,
"paramId": 17980

For my DIY scenes I use the same POST as above but I replace "scenes" with diy-scenes" and I get a list of all my DIY scenes that are associated with that device.

I got all my information on how to get the scene information from this link: https://developer.govee.com/reference/get-light-scene

How are you pulling information for each scene?

I don't much about Razor Chroma but sounds very interesting if it uses local control!

@AlgoClaw
Copy link

AlgoClaw commented Dec 5, 2024

@Hauty9

API

Ah, I see you are using Govee's official API with your own API key. Hence, you are able to pull info about your account and your configuration (and your custom made DIY scenes).

The info I get is simply by using the no-key-required public API that @wez posts at the very top of this thread. You can pull the info at https://reqbin.com/post-online if you do not have a CLI to work with. For example, you can enter the command:

curl "https://app2.govee.com/appsku/v1/light-effect-libraries?sku=H805A" -H 'AppVersion: 999999'

This specifies the model number "H805A" (as a parameter) and the "AppVersion" "999999" (as a header). If you do not specify an "AppVersion", the return message is simply "service is busy please try again later". So, I tried with an arbitrarily high number "999999". I also tried with "0" to see if the results were different, and they were.

So you don't have to do this yourself, I posted the results for 3 models (H61A8, H7039, H805A), with AppVersion 0 and 999999 here https://github.com/AlgoClaw/Govee/tree/main.

In the 999999 AppVersion for the H805A (https://github.com/AlgoClaw/Govee/blob/main/H805A_2024-12-04_AppVer999999), the code for "Thanksgiving" is the following (lines 1728-1767):

{
                "sceneId": 10775,
                "iconUrls": ["https://d1f2504ijhdyjw.cloudfront.net/img/5d449e7ad3e54350b9ab9e6a242efcd3-new_light_btn_scenes_thanks_giving%403x.png", "https://d1f2504ijhdyjw.cloudfront.net/img/7d5682af58f3e8c4f53f78e42dfc7e76-new_light_btn_scenes_thanks_giving_press%403x.png", "https://d1f2504ijhdyjw.cloudfront.net/img/2970975f8989fce8e1970624c207cb08-new_light_btn_scenes_thanks_giving_dark%403x.png"],
                "sceneName": "Thanksgiving",
                "analyticName": "Thanksgiving",
                "sceneType": 2,
                "sceneCode": 0,
                "scenceCategoryId": 0,
                "popUpPrompt": 0,
                "scenesHint": "",
                "rule": {
                    "maxSoftVersion": "",
                    "minSoftVersion": "",
                    "maxHardVersion": "",
                    "minHardVersion": "",
                    "maxWifiSoftVersion": "",
                    "minWifiSoftVersion": "",
                    "maxWifiHardVersion": "",
                    "minWifiHardVersion": ""
                },
                "lightEffects": [{
                    "scenceParamId": 17980,
                    "scenceName": "",
                    "scenceParam": "BSAyAAADAgH/AAP3FBQD/BQD/5AH/3gH/zoHFAD5AACAASA1AAADAgH/AAP3FBQD/BQD/5AH/3gH/zoHFgD5AACAASlQAAABAgH/AAP3FBQD8hQG/wAA//8AAP8AAP//AAD/iwD/EgD5AAD8ASAAAAABAgH/GQH0FBQA8hQD/10H/5EH//8AAACAAACAASlVAAABAgH/AAP3FBQD8hQG/wAA//8AAP8AAP//AAD/iwD/EAD5AAD8AQ==",
                    "sceneCode": 11286,
                    "specialEffect": [],
                    "cmdVersion": 1,
                    "sceneType": 2,
                    "diyEffectCode": [],
                    "diyEffectStr": "",
                    "rules": [],
                    "speedInfo": {
                        "config": "",
                        "speedIndex": 0,
                        "supSpeed": false
                    }
                }],
                "voiceUrl": "",
                "createTime": 1712114992028
            }

LAN Commands (H61A8)

I went back through my attempt to organize the working LAN commands for the H61A8 (https://docs.google.com/spreadsheets/d/1FokCgrgi34qqEEiy1-_AeeroNMDFz-83XSapXxNVXFI). It seems through firmware updates Govee removed nearly all commands that I identified for a scene. Previously, I identified about 45 commands that would start a scene. Now, I can only identify 13. So, even if this was a good to send LAN commands, Govee forces updates that remove them (or change them).

Separately, I previously linked the incorrect website to calculate the checksum. The site you want to use is https://www.scadacore.com/tools/programming-calculators/online-checksum-calculator/. This is the only site I can find that gives the correct result.

Looking back at the UI I made in NodeRed, I can control power, brightness, and color using LAN commands with the (very) basic info Govee provides in their guide (https://app-h5.govee.com/user-manual/wlan-guide).


LAN Commands (Generally)

Based on Craig K's (@Mavrrick) comment here https://developer.govee.com/discuss/660c7e59aa38b40025f0cf53, it seems multiple of these commands are required to be sent in a single message in order to initiate a scene.

He seems to be much more active in the development and understanding of the LAN commands.
See:

I think the H805A is here (he does not use model numbers):

@Hauty9
Copy link

Hauty9 commented Dec 13, 2024

@AlgoClaw

Thank you for all the detailed examples and descriptions! I find it kind of strange that you can pull scene ids with two different APIs. Maybe this is par for the course for other APIs but kind of wish Govee would spell it out more and make a more robust local API. Or if there was a way to pass the scenes to a Matter controller, that would solve alot of issues. I have mine integrated into SmartThings but it only has basic control and I have not found a way to trigger any scenes within SmartThings.

I will have to check out some of the links you provided and see how much time I want to put into this if Govee updates kill off some scene IDs. I have it working pretty good right now with the cloud API but I'm a fan of local control and would love to have it all locally done.

I do wish the cloud API had the ability to trigger "tap to run" scenes or groups as well. I have two sets of permanent outdoor lights to cover my house that I would love to trigger at the same time via the API but have not found a way to do that. I'm not a fan of sending the same scene to one controller then another controller with a second or two delay. The lights look mildly out of sync depending on the scene.

@AlgoClaw
Copy link

@Hauty9 @wez

SOLVED?

Okay, I think I figured it all out and completely reverse engineered the scene codes. Given just the publicly available API (no key required), you can calculate the required commands to send for any given scene.

Here is an explanation of how to do it: https://github.com/AlgoClaw/Govee/blob/main/decoded/explanation

Here is a bash script to generate a JSON for any given model: https://github.com/AlgoClaw/Govee/blob/main/decoded/govee_decoded.sh
(Let me apologize in advance -- this is some of the sloppiest coding I have ever done).

I pre-made jsons for three models.
H61A8: https://github.com/AlgoClaw/Govee/blob/main/decoded/govee_H61A8_scenes_with_commands.json
H7039: https://github.com/AlgoClaw/Govee/blob/main/decoded/govee_H7039_scenes_with_commands.json
H805A: https://github.com/AlgoClaw/Govee/blob/main/decoded/govee_H805A_scenes_with_commands.json

Now, I just need @wez to integrate this into https://github.com/wez/govee2mqtt

Let me know if anyone else has success with these.

@loebi-ch
Copy link

Wow @AlgoClaw, it seems as you've found the holy grail :-) Congratulations for solving the Govee puzzle.
I don't unterstand why developers make it so tricky for others... The history showed us that OpenSource has great potential and I don't understand why companies are doing proprietary stuff as this. They would sell much more of their physical devices if they had a more straightforward local API...

@AlgoClaw
Copy link

@loebi-ch You're preaching to the choir. I spent most of my winter break on this. They could have saved hundreds of hours (between all of us) if they just released the documentation on how to use their devices.

I recently bought another TP-Link smart dimmer switch (I have ~40 TP-Link smart devices already). Apparently TP-Link devices now require cloud authentication credentials to control the devices locally. Needless to say, I will be returning the new switch and I blocked Internet access to my existing switches. I spent a few hours looking for good alternatives, but came up short.

It seems we are moving backwards when it comes to user ownership and local control. This battle may be won, but the war is not looking good. C'est la vie, we fight on nonetheless.

@egold555
Copy link
Owner

This is amazing. Thank you all for all the work on this!

Happy to add/merge any of this documentation into this repo if you think it benefits the community.

@AlgoClaw
Copy link

@egold555 I hereby waive all rights in the linked documents and code. Please copy/modify/reuse whatever you'd like.

@Hauty9
Copy link

Hauty9 commented Dec 30, 2024

@AlgoClaw,

Nice work!! I appreciate you spending the time to figure this out!

I do have a question about how you are sending the commands. I was looking a the Christmas scene for the H805A:

"name": "Christmas",
"code": 11271,
"params_b64": "AykAAhQFAgH/GQAAAAAC+jIG/zgA/38AAP8AAAAAAP///wAAFADvAAAAACMAAhQFAAH/GQHmMjIB9DIE8QAdAP8AAP//////FgDyEgDdACAAAAABAgH/cAPbFBQA9xQD/wAAAAAAAP8AEQCAAAAAAA==",
"hex_cmd": [
"a3000107020329000214050201ff19000000007b",
"a30102fa3206ff3800ff7f0000ff0000000000d6",
"a302ffffff00001400ef00000000230002140595",
"a3030001ff1901e6323201f43204f1001d00ff70",
"a3040000ffffffffff1600f21200dd0020000053",
"a30500010201ff7003db141400f71403ff0000ec",
"a3ff00000000ff00110080000000000000000032",
"330504072c000000000000000000000000000019"
],
"b64_cmd": [
"owABBwIDKQACFAUCAf8ZAAAAAHs=",
"owEC+jIG/zgA/38AAP8AAAAAANY=",
"owL///8AABQA7wAAAAAjAAIUBZU=",
"owMAAf8ZAeYyMgH0MgTxAB0A/3A=",
"owQAAP//////FgDyEgDdACAAAFM=",
"owUAAQIB/3AD2xQUAPcUA/8AAOw=",
"o/8AAAAA/wARAIAAAAAAAAAAADI=",
"MwUEBywAAAAAAAAAAAAAAAAAABk="
]
},
{

What are you sending to the controller from this and how are you sending it? I have yet to get any kind of scene commands to trigger locally. I can get standard on/off from the documented local API to work but keep failing with the local scene control. I can send the lights this command to turn on and it works great:

{"msg":{"cmd":"turn","data":{"value":1}}}

But when I try a scene commands like this:

{"msg":{"cmd":"ptReal","data":{"command":["AixQAAAFAgL/fgPMKBTMTAHMFBQCABQFL6r/ntr+/6U0/38A/wAAAAAAAAAAACxVAAAFAgL/fgPMKBTMTAHMFBQCABQF/wAA/38A/6U0ntr+L6r/AAAAAAAAAA=="]}}}

I get nothing. Any suggestions?

@AlgoClaw
Copy link

@Hauty9

You want to use the "b64_cmd" data (from the JSON I generated) for the command field. For Christmas, try the "b64_cmd" data you posted, like this:

{"msg":	{"cmd":"ptReal","data":	{"command": ["owABBwIDKQACFAUCAf8ZAAAAAHs=","owECjIG/zgA/38AAP8AAAAAANY=","owL///8AABQA7wAAAAAjAAIUBZU=","owMAAf8ZAeYyMgH0MgTxAB0A/3A=","owQAAP//////FgDyEgDdACAAAFM=","owUAAQIB/3AD2xQUAPcUA/8AAOw=","o/8AAAAA/wARAIAAAAAAAAAAADI=","MwUEBywAAAAAAAAAAAAAAAAAABk="]}}}

I personally use a docker instance of Node-Red for the bulk of my home automation. There are a bunch of UI nodes that pull data and format it and send it to a "UDP out" node -- it is messy.

But, I send the scene commands the same way as I send power, brightness, and color commands. So, if you have those functions working, you are doing it right. It just seems the command you are sending is not correct.

wez added a commit to wez/govee2mqtt that referenced this issue Dec 30, 2024
This commit adopts the excellent reverse engineering work
carried out by @AlgoClaw in egold555/Govee-Reverse-Engineering#11 (comment)
as the way that we apply scenes.

This should result in fewer weird glitches and more accurate
application of the defined scenes.

My testing of this has been light; there is a unit test that
verifies the example from the walkthrough of the process,
and I used the CLI interface to apply a couple of scenes:

```console
./target/debug/govee lan-control --ip 192.168.1.201 scene Breathe
Loading environment overrides from "/home/wez/wez-personal/govee-rs/.env"
Computed ["o/8BAQIAAAAAAAAAAAAAAAAAAF4=", "MwUECgAAAAAAAAAAAAAAAAAAADg="]
```
@wez
Copy link
Author

wez commented Dec 30, 2024

@AlgoClaw this is great, thank you! I've pushed a version of this in govee2mqtt: wez/govee2mqtt@5de5b50

It seems to work when used via the CLI interface. I haven't tested it beyond that at this time, so I haven't made a release with these bits yet.

@wez
Copy link
Author

wez commented Dec 31, 2024

The most recent govee2mqtt release now prefers to use the LAN API with this technique

@loebi-ch
Copy link

Thank you @AlgoClaw for solving the puzzle and thank you @wez for integrating it so fast. It works like a charm. The scenes now change without any delay thanx to using the local API.

I'm wondering if we could find the corresponding local API commands for changing the single segments and setting DIY scenes and snapshots.

@Hauty9
Copy link

Hauty9 commented Dec 31, 2024

@AlgoClaw

Thank you for the explanation! It works great now! I'm really excited to bring local control to the lights as the cloud seems unreliable. This is a game changer for my setup!

To push this a bit further....have you found a way to trigger any "tap to run" scenes or turn a group on and off? I have two sets of H805a lights on my house that I want them paired together but have not found a way to do so outside of the Govee app. When I send a command to one string then the other string they are out of sync. If I use the app with the "tap to run" scenes or turn the group on and off they are closer in sync but have yet to figure out a way to do it via the API.

@AlgoClaw
Copy link

AlgoClaw commented Dec 31, 2024

@Hauty9

Glad to hear it. It is nice to know this works on different models too.

For groups, I have not found a way to access a "group" defined in the app. Instead, I define my own groups locally on my sever (in Node-Red).

As far as syncing goes, I send the command to all my devices (or a subset of devices) simultaneously. I am not sure if it is precisely simultaneous, but 80% of the time, the lights are synced together. In Node-Red, this is accomplished by linking one input node to multiple outputs ("Govee1", Govee2", etc., see below)
image
My setup is likely not what most people are using.

How are you sending the commands? what language/script type?

Can you make a function/script for setting a scene to device? Example:
setgovee(device, scenename)

Then make a script to call a series of that function for each light ("light1", "light2", "light3")? Example:
setgovee("light1", "Halloween-A")
setgovee("light2", "Halloween-A")
setgovee("light3", "Halloween-A")

@Hauty9
Copy link

Hauty9 commented Dec 31, 2024

@AlgoClaw

I use a home control/automation system called RTI. There is a driver designed to send UDP commands to a specified IP. So for my case I would need two instances of the driver in my system as the driver only has capabilities to send to a single IP for each instance.

What I'm actually just thinking about, that I will need to test, is that since its local control I can use two instances of the driver and send commands to each Govee controller in less than a second. In RTI you build macros with the driver commands you want to use. I'm thinking since its local and two different Govee controllers, the commands might not get lost like they do when I send commands to the cloud API. I found I needed to add a couple second delay when sending commands to cloud API or else the second command was lost.

I gotta do some re-programming and testing but I'm thinking the speed of local control along with two driver instances might be the key to get the devices as close to sync'd up as possible.

@AlgoClaw
Copy link

I did not give proper appreciation and credit before. The techniques I used were based overwhelmingly on the work already performed by @wez and @Mavrrick.

Specifically, @wez 's:

  • Posting of the API to pull scene data (described in the first comment here).
  • Documentation of the Bluetooth commands, formation of the hex codes, conversion to base64, JSON format/wrapping, and UDP communication (described in the first comment here)
  • Excellent Home Assistant integration via https://github.com/wez/govee2mqtt and speedy updates to include local control. (I have actually starting using HA again because of this).

And, @Mavrrick 's

  • Insight that multiple commands are required to set most scenes (based on his code here and posts on Govee's forum)
  • Library of commands (I have limited experience with Hubitat, but relied on those libraries for confirming results)

Initially, I was manually sniffing Bluetooth packets, extracting the payload, converting the hex to base64, then searching github to see if anyone else already posted that exact base64 string. Each time, there would be one-or-two results @Mavrrick included in his libraries. This let me know the conversion was correct -- but also that the number of commands needed for a scene matched the number of Bluetooth packets sent.

After combining what @wez and @Mavrrick provided, I actually considered the problem "solved". However, we would have to manually sniff packets for every scene on every device--and manually re-sniff whenever Govee updated or added new scenes.

The only contribution I really made was to try deciphering the "scenceParam" to see if it matched the Bluetooth hex commands--which it did, with some additional work.

Also, thank you to @Hauty9 . I gave up on this several times but kept coming back because @Hauty9 kept the issue active (bumping it to the top of my inbox).

@loebi-ch
Copy link

loebi-ch commented Jan 1, 2025

@AlgoClaw what Bluetooth sniffer and how have you used it to sniff the packages sent to the Govee device?

@Mavrrick
Copy link

Mavrrick commented Jan 1, 2025

@AlgoClaw This is amazing work, but i have a few questions as i am having some unexpected results using the script output from this process.

First are you familiar with the new ptURL command and does this take any account for that. I have yet to find any way to work with scenes that use the ptURL command at all. This ptURL command is found on a few new devices like the Net Lights, the Curatin Lights 2, and the Christmas Lights Gen 2

Second how many devices were checked. I am running into inconsistencies with what I had already extracted. Simply put when using your script to extract for the H6066 device i get one command string that is fairly different from what i had already extracted. I thought the difference would be related to maybe a speed value, but it doesn't appear to be working.

My process pulls in a command string of

"cmd": "["owABAgQnFR0BAAEFAAIAD57//x0=", "o/9lAAAAAAAAAAAAAAAAAAAAADk=", "MwUEDQoAHQAAAAAAAAAAAAAAACg="]"

Your script pulls in a command string of

"b64_cmd": [
  "owABAgISAAAAACcVHQEAAQUAApg=",
  "o/8AD57//2UAAAAAAAAAAAAAAKg=",
  "MwUEDQoAAAAAAAAAAAAAAAAAADU="
]

The extra \ and " for data handling aside the strings have some significant differences. I am really curious to hear from others on how this works for them.

The way my extract works is by using a call to the AWS service Govee uses with their Phone app. That app set of data when going to the home page and lists various things including Tap-To-Runs. Those tap to runs include in their data a section for iotmsg that includes the entire command. For the most part that has worked well to retrieve working commands, but is a pain. I was really excited to use this method to generate the list in full. The commands though are not matching up. I have tried several different commands now and none of them have matched and they don't appear to work.

Ofcourse my testing so far has been with commands generated by your script. Do you believe the script may have some issues?

@AlgoClaw
Copy link

AlgoClaw commented Jan 2, 2025

@loebi-ch

My Bluetooth sniffing method is very low-tech. I use a setting available in the "Developer options" on Android.

Steps:

  1. Disable Bluetooth (if enabled)
  2. Enable packet capture
    Settings > System > Developer options > Enable Bluetooth HCI snoop log > Enabled
  3. Enable Bluetooth
  4. Perform Bluetooth actions
  5. Disable Bluetooth
  6. Disable packet capture
    Settings > System > Developer options > Enable Bluetooth HCI snoop log > Disabled

After step 6, the log file should be located at:
/data/misc/bluetooth/logs/btsnoop_hci.log

I then copy this to my computer and open it in WireShark.

NOTE 1: When you enable and disable the HCI snoop log, Bluetooth has to be disabled. If Bluetooth is enabled on either side, the log file (likely) will not save.

NOTE 2: A lot of people on various forums on the internet say your phone needs to be rooted to capture Bluetooth data. I don't know if this is true. My phone is rooted, but I don't see why that is required for the above method.

NOTE 3: Make sure you are sending commands to the Govee device via Bluetooth. I wasted so much time accidentally sending commands via the cloud. When you are in the Govee app, controlling a device, there is a Bluetooth or WiFi symbol at the top, make sure you are using Bluetooth. If you want to force Bluetooth, you can disable WiFi and cell data.


@Mavrrick

  1. I have no experience with the ptURL command. In fact, I only add "ptReal" because of @wez 's first comment. The other commands provided by Govee in their documentation are "scan", "turn", "brightness", "devStatus", and "colorwc" -- which are all somewhat descriptive. But, "ptReal" and "ptURL" are not very descriptive. What is "ptURL" used for? Is it used instead of "ptReal" for those newer devices?

  2. I spot checked ~30 scenes on the H61A8 and ~10 on the H7039 (the only two models I own). Further, it seems Hauty9 has had success with the H805A.

  3. For the H6066, does the b64_cmd from my script work? When I convert the commands from your method (from base64 to hex) the results are:

a30001020427151d010001050002000f9effff1d
a3ff650000000000000000000000000000000039
3305040d0a001d00000000000000000000000028

This is interesting. For the last command, there is the same prefix (330504) and converted sceneCode (0d0a). However, there is a "1d" in the following section... This would imply that the fixed padding (28x zeros, 14x hex zeros) is not correct and that some data may be present there (at least sometimes). I add padding per wez's comment above "zero-pad out to 19 bytes" -- but this may not be true in all cases.

"1d" (hex) = "29" (dec) = "HQ==" (base64)

None of those seem to match anything from the raw data. I'll think on it.

  1. Interesting. You are logging the commands via the cloud method. Try logging the "mirage" scene via Bluetooth (as described above) and see if the results are the same? If not, that would be even more interesting.

  2. The script could have many issues. It would not surprise me at all. That being said, the commands work on three different model numbers (that I am aware of, so far).

    After I made the discovery around 6pm on the 30th, I wrote up the explanation document, then stayed up until 4am writing the bash script. As time went on, I cared less and less about readability, cleanliness, and conciseness and just wanted results that made sense. Towards the bottom of the script, in the "Format JSON" section, you can really see how lazy I got... I use a nasty combination of regex find-and-replace commands with a series of "jq" commands (which I have never used before), and needless writing the data to different files -- just to move some characters around.

    I am an amateur/hobbyist programmer and even I am kind of embarrassed by that script. I might try to clean up up in the coming week or so. Please feel free to re-write it in any language of your choice. I can work with any language (except Python) with a preference to work in the Linux CLI (hence my tendency for shell scripts).

    I know at least some commands line up -- this is how I confirmed my results initially. For example, if you search the first base64 command for "Forest" on GitHub (https://github.com/search?q=%22owABBwIDJgABAAoCAf8ZAbQKCtk%3D%22&type=code), there are 4 results for code in your repositories.

@loebi-ch
Copy link

loebi-ch commented Jan 2, 2025

I hope it's okay to post that inside this Github issue...

I invested a few hours to try to set the segments of a Govee light by local API.

My use case: Most of the time I want to set my Govee lights to a static gradient and not to a fancy animated scene.
So far, I created snapshots in the Govee app and used the Cloud API to set the light to the appropriate snapshot. But this is very awkward, because you have to create snapshots for each individual light and there is a big latency when using the cloud API.

My knowledge is based on the very useful and detailed post of @Mavrrick found here: https://www.loxforum.com/forum/faqs-tutorials-howto-s/446672-govee-ble-local-api-segmentsteuerung-szenen that explains in detail how the "Grafiti mode" works. Thank you Mavrrick!

Here is my code in my favourite coding language (C#). It's quite straightforward and easy to translate to other programming languages.

//------------ CONFIGURATION----------------------------------------
string deviceIpAddress = "192.168.1.36";
string[] gradientColors = ["ff8800", "ff0000", "a035ff"]; //sunset
//string[] gradientColors = ["ff0000", "00ff00", "0000ff"]; //rainbow
//string[] gradientColors = ["ff7114"]; //warm white

//------------------------------------------------------------------------

//Define segments depending on specified gradient colors count
int[] segmentSizes;
switch (gradientColors.Length)
{
    case 1:
        segmentSizes = [14];
        break;
    case 2:
        segmentSizes = [7, 7];
        break;
    case 3:
        segmentSizes = [5, 4, 5];
        break;
    case 4:
        segmentSizes = [4, 3, 3, 4];
        break;
    case 5:
        segmentSizes = [3, 3, 3, 3, 2];
        break;
    case 6:
        segmentSizes = [3, 2, 2, 2, 2, 3];
        break;
    case 7:
        segmentSizes = [2, 2, 2, 2, 2, 2, 2];
        break;
    default:
        Console.WriteLine("[ERROR] You have to specify at least 1 and max 7 gradient colors!");
        return;
}

//Reverse gradient colors (as Govee lights start from bottom to top and I want to define it from top to bottom)
gradientColors = gradientColors.Reverse().ToArray();

//Generate Govee LAN API command
string command = "01 pc"; //pc = packet count (will be replaced afterwards when we know how many packets we have)
command += "03"; //Grafiti mode
command += "09"; //Animation direction (0a: Down; 09: Up; 02: Cycle; 13: Fading; 0f: Sparkle; 14: Breathe)
command += 0.ToString("X2"); //speed of animation (0-100)
command += 0.ToString("X2"); //intensity of background (0-100)
command += "000000"; //background color RGB in hex
command += " " + segmentSizes.Length.ToString("X2"); //Segment count
int pixelNumber = 0;
for (int segmentIndex = 0; segmentIndex < gradientColors.Length; segmentIndex++) //for each segment
{
    command += " " + segmentSizes[segmentIndex].ToString("X2"); //Segment size
    command += " " + gradientColors[segmentIndex]; //Segment color RGB in hex
    for (int i = 0; i < segmentSizes[segmentIndex]; i++) //for each pixel in the segment
    {
        command += " " + pixelNumber.ToString("X2"); //Pixel number in hex
        pixelNumber++;
    }
}

//Split Govee LAN API command into packages of 17 bytes (20 bytes - 2 starting bytes - 1 checksum byte)
command = command.Replace(" ", "");
List<string> packages = Enumerable.Range(0, (int)Math.Ceiling((decimal)command.Length / 34)).Select(i => command.Substring(i * 34, Math.Min(34, command.Length - i * 34))).ToList();

//Replace "pc" (packet count) in the first package by the actual count of all packages
packages[0] = packages[0].Replace("pc", packages.Count.ToString("X2"));

List<string> base64Packages = [];
for (int packageIndex = 0; packageIndex < packages.Count; packageIndex++)
{
    string package;
    if (packageIndex < packages.Count - 1)
    {
        //Add "a3" and the number of the package to the beginning of the package
        package = "a3" + packageIndex.ToString("X2") + packages[packageIndex];
    }
    else
    {
        //For the last package we add "a3ff" to the beginning of the package
        package = "a3ff" + packages[packageIndex];
        package = package.PadRight(38, '0');
    }

    //Calculate XOR checksum of the package and add it to the end of the package
    byte xorTotalByte = 0;
    for (int i = 0; i < package.Length; i += 2)
    {
        xorTotalByte ^= byte.Parse(package.Substring(i, 2), NumberStyles.AllowHexSpecifier);
    }
    package += xorTotalByte.ToString("X2");
    package = package.ToLower();

    //Convert package to base64
    List<byte> _bytes = [];
    for (int i = 0; i < package.Length; i += 2)
    {
        _bytes.Add(Convert.ToByte(package.Substring(i, 2), 16));
    }
    base64Packages.Add(Convert.ToBase64String(_bytes.ToArray()));
}

//Last package always has to be "MwUKIAMAAAAAAAAAAAAAAAAAAB8="
base64Packages.Add("MwUKIAMAAAAAAAAAAAAAAAAAAB8=");

// Build payload to send to Govee device
JObject jData = new()
{
    ["msg"] = new JObject
    {
        ["cmd"] = "ptReal",
        ["data"] = new JObject
        {
            ["command"] = new JArray(base64Packages)
        }
    }
};
byte[] bytes = Encoding.ASCII.GetBytes(jData.ToString());
Console.WriteLine("Sending command to Govee light @ " + deviceIpAddress + ":4003\n[" + string.Join(", ", base64Packages.Select(t => "\"" + t + "\"").ToList()) + "]");
UdpClient udpClient = new();
udpClient.Send(bytes, bytes.Length, deviceIpAddress, 4003);

I use the calculated Govee command(s) inside Home Assistant by defining a shell_command in configuration.yaml:

shell_command:
  govee_set_sunset_gradient_in_office: echo '{"msg":{"cmd":"ptReal","data":{"command":["owABAwMJAAAAAAADBaA1/wABAsQ=", "owEDBAT/AAAFBgcIBf+IAAkKCyg=", "o/8MDQAAAAAAAAAAAAAAAAAAAF0=", "MwUKIAMAAAAAAAAAAAAAAAAAAB8="]}}}' | nc -w 2 -u 192.168.1.36 4003

And I call it in an automation like this:

action: shell_command.govee_set_sunset_gradient_in_office

This is a very static approach, because I couldn't use any parameters in the shell_command (for IP address and the gradient colors).

Now I'm thinking about exposing an individual service in Home Assistant that's taking the IP address and the segment colors so that I can call:

action: whatever_service.set_gradient
data:
  ip: 192.168.1.36
  colors:
    - ff8800
    - ff0000
    - a035ff

Maybe that's also interesting for others and I think it would be quite easy for @wez to expose such a service, if this is a need also for others...

What do you think?

@wez
Copy link
Author

wez commented Jan 2, 2025

think it would be quite easy for @wez to expose such a service

I'm not sure if it is possible to expose a home assistant service via mqtt, but it would be doable to expose a REST API endpoint in govee2mqtt that could do the heavy lifting.

@wez
Copy link
Author

wez commented Jan 2, 2025

FWIW, over in wez/govee2mqtt#353 some users are noting that this enhanced scene setting technique doesn't work for every device.

One frustration I have with Govee's control scheme is that there is no direct response on whether any given command did a thing. It would be great if there was a way to determine that a scene had been applied--I think this must be possible (perhaps via BLE or IoT?) because I noticed in the Govee app the other day that it reports the scene name that was applied via ptReal when you first drill down into a device.

@Mavrrick
Copy link

Mavrrick commented Jan 2, 2025

@wez It would be interesting to see what devices do and what devices don't work.

I have a theory on that after taking a look at the devices @AlgoClaw tested with. My theory is that this is about device type as much as it anything else. All of the devices @AlgoClaw appears to have validate with are String/strip type devices. What i mean by that is they all run in a series of pixels with no fancy geometric lighting effects with them. The H6066 device i initially started testing with is a Govee Glide Hexa Pro kit. The H6066 didn't work at all with any of the commands passed.

I just ran the script for one of my H6172 strips and compared it to my existing command list I had extracted a while ago. The spot checking I did indicated everything was matching up exactly. So at the least that LED Strip matches up perfectly.

I feel like i need to go through and test the other types of devices to see how close the commands match up.

@AlgoClaw

The ptURL command was something that I found recently with the help of a user as they were having a problem performing the scene extraction in my integration my process on Hubitat. Simply put when my process calls the AWS endpiont we get back a long string that includes all of the Home page data for the Govee Home app. The integration parses down and find a specific group for Tap-To-Runs. Then each tap to run has each action reviewed for certain criteria that make it a Govee Scene, Snapshot, or DIY. Part of that criteria was looking for the ptReal command. Once that was found it would extract out the iotmsg and parse out the cmd value for further processing and saving in the integration.

After a far amount of back and forth and confirming the user had everything right we dug into the raw data to find the ptURL command was in place of ptReal. The command structure was also very different. Below you can see some examples of what was stored from the extraction process for a H70B5. Even worse is that unlike ptReal, the ptUrl command doesn't seem to work when submitted via the LAN Api

        "1003": {
            "cmdType": "ptReal",
            "name": "Star",
            "cmd": "[\"MwUEJwAAAAAAAAAAAAAAAAAAABU=\"]"
        },
        "1004": {
            "cmdType": "ptReal",
            "name": "Meteor",
            "cmd": "[\"MwUEJgAAAAAAAAAAAAAAAAAAABQ=\"]"
        },
        "1005": {
            "cmdType": "ptUrl",
            "name": "Aurora",
            "cmd": "[\"/xQHAABodHRwOi8vYXBwLmdvdmVlLmNvbS9iZmYtZGV2aWNlL3YxL2VmZmVjdC9iaWctY29tbWFuZD9pZD04MDAy\", \"MwUEkyEAAAAAAAAAAAAAAAAAAIA=\"]"
        },
        "1006": {
            "cmdType": "ptUrl",
            "name": "Reindeer",
            "cmd": "[\"/5QIAABodHRwOi8vYXBwLmdvdmVlLmNvbS9iZmYtZGV2aWNlL3YxL2VmZmVjdC9iaWctY29tbWFuZD9pZD0yNjg4OA==\", \"MwUElCEAAAAAAAAAAAAAAAAAAIc=\"]"
        }

This ptURL command is very new and so far I have only seen it on a few devices that were released in the last few months.

Interestingly your process does create a command for the ptURL scenes, but when i reviewed them they were very , very long. like 80+ commands vs 7-8 of most scenes on other devices.

@loebi-ch I think you maybe giving me credit for something I wasn't associated with, or at least nothing in that link. In anyway i don't think that was me, maybe another Mavvrick :)

@AlgoClaw
Copy link

AlgoClaw commented Jan 2, 2025

@Mavrrick @loebi-ch @wez

In the link provided by @loebi-ch, there is a link to another post worth looking at https://blog.coding.kiwi/reverse-engineering-govee-smart-lights/

Also, @Mavrrick on the loxforum thread, at the bottom (most recent post) there is mention that the prefix is "a4" for the "Govee Christmas tree chain H70C4". I wonder if this change would work for those devices currently not working? Simply changing the prefix to "a4" (instead of "a3"). "a3" works on my devices -- so one of y'all could give it a try.


It's unfortunate it does not work for all models. :/

Regarding device feedback, I have found several quarks/bugs. For any scene requiring multiple commands, if you send only the last command (e.g., "MwUE1AAAAAAAAAAAAAAAAAAAAOY=" for "Forest"), the lights will restart their already-selected scene (but they do not change to "Forest").

Further, if you send only the last command, the app will show the scene changed to "Forest" -- even though it did not actually change (if you have scene selection in the app already open, you have to exit out of the device and re-enter the device's scene selection).

Conversely, if you send all commands except the last command, the scene does successfully change -- but the change is not reflected in the app. Effectively, that last command is optional for control.

If you wanted to be devious, you could mix-and-match. For example, using the H61A8, the first 7 commands below set "Forest" without the last command to change the setting in the app. Then, I add the last command for "Meteor shower". Thus, the scene "Forest" is set on the device, but the app will show the scene "Meteor shower" is selected.

"owABBwIDJgABAAoCAf8ZAbQKCtk=",
"owECyBQF//8AAP//////AP//lBI=",
"owL/ABQBlgAAAAAjAAIPBQIB/wo=",
"owMUAfsAAAH6CgQE/wC0/wBH/7M=",
"owT/4/8AAAAAAAAAABoAAAABAl0=",
"owUB/wUByBQUAu4UAQD/AAAAAJI=",
"o/8AAAAAAAAAAAAAAAAAAAAAAFw=",
"MwUE5AAAAAAAAAAAAAAAAAAAANY="

So, if you really want to gaslight somebody into thinking a scene goes by a different name, this is how to do it :)

Also, I noticed when using the scenes set via cloud integration in govee2mqtt, the app does not show any selected scene. That is, the cloud integration via govee2mqtt is the equivalent of sending all commands except the last command. So, there is no way to tell in the Govee app what has been set.


What does the "devStatus" command return? Node-RED is problematic if I remove the container and need to takeover ports 4002 and 4003 from govee2mqtt. @wez is there some way for me to enable verbose reporting for ports 4002 and 4003 in the container logs?

@wez
Copy link
Author

wez commented Jan 2, 2025

@AlgoClaw:

@wez is there some way for me to enable verbose reporting for ports 4002 and 4003 in the container logs?

You can set the log filter to govee::lan_api=trace:

RUST_LOG=govee::lan_api=trace

(set that in the env for the docker container, or if you're using the hass addon, there is an option for this in the UI)

and look for process_packet for the port 4002 traffic:

https://github.com/wez/govee2mqtt/blob/bb4ba8e99c1e17b2598df74cc5a50028d4435369/src/lan_api.rs#L451-L454

and send_request for the port 4003 traffic:

https://github.com/wez/govee2mqtt/blob/bb4ba8e99c1e17b2598df74cc5a50028d4435369/src/lan_api.rs#L196

@Mavrrick
Copy link

Mavrrick commented Jan 2, 2025

May have found a pattern or at least something for the H6066

I took the command created by the script, and the command i already had for a scene and converted them both back to Hex

Here is the hex code for the script and what i had for scene Mirage

My command:

a30001020427151d010001050002000f9effff1d
a3ff650000000000000000000000000000000039
3305040d0a001d00000000000000000000000028

Script

a300010202120000000027151d01000105000298
a3ff000f9effff650000000000000000000000a8
3305040d0a000000000000000000000000000035

I see three differences on line 1. The first is related to a change from 02 to 04 in positions 9 and 10. I think The procedure indicates that should always be 02 so i suspect this is one error of concern. How do we determine that. Then I noticed in the script output it looks like there is a value from positions 11-10 that is missing from the command I received from the method I use. If those characters are removed then the rest of the command looks like it matches up. Lastly there seems to be a new value in the padded 0's in the final line I am suspicious about it relating to the speed for the scene, but need to further test that.

I validated again with scene Dreamland and saw the same thing happen. The Characters in position 11-20 where slightly different but regardless from the script, but they were missing from my working command. Further testing is needed, but this looks promising

@AlgoClaw
Copy link

AlgoClaw commented Jan 2, 2025

@Mavrrick

Yeah, I wrote about the "1d" in the padding in my reply to you (#11 (comment))

These 2 sites provide good insight into what may be happening in that last command:

(they have good info on how to change sections too @loebi-ch). The first link is effectively the same process I went through.

However, I am 99% sure that the last command is not actually required to set the scene -- it only changes the status in the app (see #11 (comment))

The "Mirage" info for the H6066 has the following "scenceParam":

EgAAAAAnFR0BAAEFAAIAD57//2U=

Converted to Hex, this is:

120000000027151d010001050002000f9effff65

The correct commands (you posted) are:

a30001020427151d010001050002000f9effff1d
a3ff650000000000000000000000000000000039
3305040d0a001d00000000000000000000000028

Thus, most of the first line can be taken from the converted scenceParam:

first line : a300010204 27151d010001050002000f9effff 1d

scenceParam: 1200000000 27151d010001050002000f9effff 65

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement New information regarding a product
Projects
None yet
Development

No branches or pull requests

7 participants