jangxx / node-magichome

An incomplete implementation of the functionality of the "Magic Home" app. Partially a port of https://github.com/Danielhiversen/flux_led to Node.js
ISC License
124 stars 26 forks source link

new Type 0x35 #24

Closed renaiku closed 4 years ago

renaiku commented 4 years ago

Hello me again. I got new bulbs, and this ones also have cold white (not the simulated one with rgb = 255)

When cold white and brightness at 100%:

{
  "type": 53,
  "on": true,
  "mode": "color",
  "speed": 50,
  "color": {
    "red": 0,
    "green": 0,
    "blue": 0
  },
  "warm_white": 0,
  "cold_white": 255
}

I can't figure out if I should use masks or not since turnOn/turnOff works like a charm but setColor always set the bulb in warm white mode.

I'm avalaible to run tests after work hours ( Central European Time + 1 )

jangxx commented 4 years ago

Setting the cold white value is actually not supported by this library at the moment (which is also stated in the README), since I don't know what the command to do it looks like. The normal command to set the color can only modify the RGB and warm white values and I have no way to find out what the command for cold white is supposed to look like, since none of my controllers support this feature. The python library this project was originally based on, also doesn't support cold white, and I've never actually seen the feature in any library for any other programming language either.

If you want to see this feature, you can either find another library which implements it, so I can take the info from there, or you can capture some network traffic and either send it to me for analysis, or analyze it yourself if you know how to do that. Then we could use that information to build a setColdWhite method.

jangxx commented 4 years ago

This also means that you don't need to set the masks, because the masks are completely separate from setting the cold white value.

renaiku commented 4 years ago

I will log the hex values at 0, 50 and 100% brightness and compare them to the warm white mode. I will log it here.

EDIT: values returned by this library

COLD WHITE
81 35 23 61 01 10 00 00 00 00 07 ff 0f 60            100%
81 35 23 61 01 10 00 00 00 00 07 7f 0f e0            50%
81 35 24 61 01 10 00 00 00 00 07 00 0f 62            0%

WARM WHITE
81 35 23 61 01 10 00 00 00 f9 07 00 0f 5a            100%
81 35 23 61 01 10 00 00 00 7f 07 00 0f e0            50%
81 35 24 61 01 10 00 00 00 00 07 00 0f 62            0%

I will now try to catch values sent from the phone with wireshark. 🤞

jangxx commented 4 years ago

Like I said, there is no way to produce a packet which changes the cold white values from this library at the moment. The values you posted are the replies to the query command starting with 0x81. The color change command starts with 0x31, but you can only set red, green, blue and warm white values with it.

We also support:

Following this pattern, there might be a command 0x91 or 0x21, which can set the cold white values. Let me know if you find anything, and consider posting your wireshark traces otherwise.

renaiku commented 4 years ago

Looks like theres a speical feature to set both and cold at the same time 78786340_846196192478759_6780518600236072960_n

here are the raw values sent by the phone and the explanations from the flux led python lib:

COLD WHITE
31 00 00 00 00 00 0f 0f 4f           0%
31 00 00 00 00 ff 0f 0f 4e           100%

WARM WHITE
31 00 00 00 00 00 0f 0f 4f           0%
31 00 00 00 ff 00 0f 0f 4e           100%

BOTH AT THE SAME TIME 
31 00 00 00 00 00 0f 0f 4f           0%
31 00 00 00 42 3e 0f 0f cf           50%
31 00 00 00 83 7c 0f 0f 4e           100%

sample message for 9-byte LEDENET protocol (w/ checksum at end)
31 bc c1 ff 00 00 f0 0f
 |  |  |  |  |  |  |  | 
 |  |  |  |  |  |  |  terminator
 |  |  |  |  |  |  write mode (f0 colors, 0f whites, 00 colors & whites)
 |  |  |  |  |  cold white
 |  |  |  |  warm white
 |  |  |  blue
 |  |  green
 |  red
 persistence (31 for true / 41 for false)

So we need to set the values of the 6th byte. And probably a function that sets both too ^^.

renaiku commented 4 years ago

That's what you were asking for ?

jangxx commented 4 years ago

Oh I see, so this actually uses the "other" protocol, which I've ignored until now. I'll see what I can do.

jangxx commented 4 years ago

Okay, so apparently these cold white controllers use an additional byte in the "set color" commands, which is just stupidly hard to map onto the current design of the API. I probably need a new option (cold_white: true or something like that), new methods like setColdWhite, setWhites, setColorAndWhites, etc. and also modify the color sending method to send either 8 or 9 bytes according to the setting. I'm really not looking forward to implementing this garbage. Why oh why couldn't they just add a new command, instead of having one with variable length 🤬

Edit: And also all my assumptions were wrong and you actually do need to set the masks apparently.

renaiku commented 4 years ago

😂 looks like i ruined the end of the week hahahahaha. Sorry for that.

renaiku commented 4 years ago

Ok so, I'll try to decompile the Magic Home Pro app. Open it in android studio. Rewrite/rename variables and functions to be readable. Try to port it in js.

Good luck to me.

jangxx commented 4 years ago

I implemented methods to change the cold white values in the new_features branch, which was surprisingly not as much work as I anticipated. Because I don't have any controllers that support this feature, I could only test the changes to the extent that nothing breaks. Please check if the new methods, as well as the new cold_white_support option, do what they're supposed to do. You can find documentation about the new methods in the README.

If everything works alright, I will implement the new methods in the cli and publish a new version to npm.

renaiku commented 4 years ago

everything seems to work fine ! I've tried to set color, warm white and cold white.

Id had to use setWhites to test cold white since theres no function to set the cold on its own.

I also tried setWhites(255,255, callback). The bulb seems to ignore it. But splitting 255 between ww and cw works fine. You might want to add (or explain in the readme) a protection to have the sum <= 255.

You made an awesome job. You saved me hours of recoding the android app by reversing it lmao.

THANKS.

You lib is also the first one to handle the cold whites correctly ;) ggs 🎉

(please answer here when you publish a new version to npm)

jangxx commented 4 years ago

Id had to use setWhites to test cold white since theres no function to set the cold on its own.

Yes, and I'm not planning on adding one. The historical reason for the split was the existence of bulbs where both had to be controlled separately as well as some strip controllers with separate connectors for colors and whites. I'm pretty sure there are no bulbs or controllers which only support cold white while not supporting warm white however, so I think the split between colors and whites is consistent as it is.

I also tried setWhites(255,255, callback). The bulb seems to ignore it. But splitting 255 between ww and cw works fine. You might want to add (or explain in the readme) a protection to have the sum <= 255.

Wow, that's super weird and also not something the python library seems to handle at all. I'll not build in any "protection", since it's possible that only bulbs have this limitation, while controllers connected to strips might be able to set the sum of both values to a higher value, I will add it to the documentation though.

I'll publish it to npm tomorrow some time during the day.

renaiku commented 4 years ago

Super nice 👍

I'll have work on my side to don't break my features for the old bulbs, i might create a wrapper for this lib that handles the Options in the control depending on the model name 🤔

I have listed these ones atm, gathering from other libs and testing with my devices:

const MODELS = {
  HF_LPB100_ZJ: 'HF-LPB100-ZJ',
  HF_LPB100_ZJ002: 'HF-LPB100-ZJ002',
  HF_LPB100_ZJ001: 'HF-LPB100-ZJ001',
  HF_LPB100_ZJ011: 'HF-LPB100-ZJ011',
  HF_LPB100_ZJ00: 'HF-A11-ZJ00',
  HF_LPB100_ZJ200: 'HF-LPB100-ZJ200',
  HF_A11_ZJ: 'HF-A11-ZJ',
  ZJ_VOICE001: 'ZJ-Voice001',
  AK001_ZJ100: 'AK001-ZJ100',
  AK001_ZJ2101: 'AK001-ZJ2101'
}

afaik, AK001-ZJ2101 is the only model to have 5 channels RGBWarmCold, but the android apps fake the cold by setting RGB to the same value (its a cold white blue depending on the "quality" of the model).

jangxx commented 4 years ago

The new version 2.4.0 has been published to npm. If you have a minute, I'd be happy if you could test the new cli commands really quick, but other than that, I think this feature is done.

renaiku commented 4 years ago

never used cli commands before. only requires in my files. Have you got a link that explains how to do it ? I'll gladly help.

renaiku commented 4 years ago

Oh forget it, I just realized that you were talking about command lines 🤣 I'll try when I got a moment (probably Sunday)