Wrong state change

Hello Everybody :smile: !


I'm a new user of node-red and I need some help about a project :slight_smile:

I try to make my Connected Lamp Xiaomi yeelight reacting to an incoming notification on my android phone.
I have realised the code, he is working but there is such a little problem :

I have code a feature that make blink the light when she is off and vice versa shutdown it during a short time and then switch then on again. When the lamp is exctinct it works nice but when she is on it just shut down the light and never repower them...

In the debug window I have a thing like that :

On state --> Off state :


# code block
13/01/2019 à 13:09:18[node: d2d308bf.83c38](http://192.168.0.18:1880/#)

msg.payload : string[12]

"{"on": true}"

13/01/2019 à 13:09:21[node: d2d308bf.83c38](http://192.168.0.18:1880/#)
msg.payload : string[13]

 "{"on": false}"

Off state --> On state :


# code block
13/01/2019 à 13:09:39[node: d2d308bf.83c38](http://192.168.0.18:1880/#)
    msg.payload : string[13]

`    "{"on": false}"`

13/01/2019 à 13:09:40[node: d2d308bf.83c38](http://192.168.0.18:1880/#)
msg.payload : string[13]

`"{"on": false}"`

Here is my flow and the node i'm using :

Flow

[{"id":"3e50c602.1c94ca","type":"tab","label":"Nofification trigger","disabled":false,"info":"A flow who blink shortly the Lamp when an notification\narrived on your phone.\nWork with On/Off State.\nAuthor : GridexX"},{"id":"4d78e92d.1362c8","type":"function","z":"3e50c602.1c94ca","name":"inverse power","func":"msg.payload = flow.get('pow');\nif (msg.payload===false) msg.payload='{\"on\": true}';\nelse msg.payload='{\"on\": false}';\nreturn msg;","outputs":1,"noerr":0,"x":1100,"y":680,"wires":[["d9fd4bd7.12fd78","4564cfa3.10991"]]},{"id":"6ed638a.9d06748","type":"switch","z":"3e50c602.1c94ca","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":550,"y":660,"wires":[["92531e4b.a896c","cdc69864.95eed8"]]},{"id":"527d4ba4.18a0bc","type":"function","z":"3e50c602.1c94ca","name":"False","func":"return {payload : false};","outputs":1,"noerr":0,"x":410,"y":620,"wires":[["6ed638a.9d06748"]]},{"id":"db123eec.9cc358","type":"inject","z":"3e50c602.1c94ca","name":"Turn true","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":700,"wires":[["6ed638a.9d06748"]]},{"id":"92531e4b.a896c","type":"yeelight-compat-hue-state","z":"3e50c602.1c94ca","name":"Get State","server":"1b82c79a.0adf18","x":530,"y":500,"wires":[["b079f31a.68535","527d4ba4.18a0bc"]]},{"id":"30bd23aa.abe554","type":"delay","z":"3e50c602.1c94ca","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":920,"y":680,"wires":[["4d78e92d.1362c8"]]},{"id":"d9fd4bd7.12fd78","type":"yeelight-compat-hue-out","z":"3e50c602.1c94ca","name":"","server":"1b82c79a.0adf18","x":1010,"y":880,"wires":[]},{"id":"cdc69864.95eed8","type":"function","z":"3e50c602.1c94ca","name":"get power","func":"msg.payload = flow.get('pow');\nif (msg.payload===true) msg.payload='{\"on\": false}';\nelse msg.payload='{\"on\": true}';\nreturn msg;","outputs":1,"noerr":0,"x":740,"y":680,"wires":[["30bd23aa.abe554","d9fd4bd7.12fd78","4564cfa3.10991"]]},{"id":"4564cfa3.10991","type":"debug","z":"3e50c602.1c94ca","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1130,"y":800,"wires":[]},{"id":"b079f31a.68535","type":"function","z":"3e50c602.1c94ca","name":"Set State Flow","func":"var onState = msg.payload.state.on;\nflow.set('pow',onState);","outputs":1,"noerr":0,"x":800,"y":500,"wires":[[]]},{"id":"c59c61a1.b8c13","type":"function","z":"3e50c602.1c94ca","name":"Get Back State","func":"if(msg.payload===false) msg.payload='{\"on\": true}';\nelse msg.payload='{\"on\": false}';\nreturn msg;","outputs":1,"noerr":0,"x":1080,"y":1200,"wires":[["247acafc.6ac866","d2d308bf.83c38"]]},{"id":"5e9fcd8e.ac8f54","type":"inject","z":"3e50c602.1c94ca","name":"Get Notification","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":320,"y":1200,"wires":[["a6dfac85.b1ace8","4f47c7f1.744b9"]]},{"id":"a6dfac85.b1ace8","type":"yeelight-compat-hue-state","z":"3e50c602.1c94ca","name":"Get State","server":"1b82c79a.0adf18","x":510,"y":1060,"wires":[["67f02d96.dfef44"]]},{"id":"106de578.09a63b","type":"delay","z":"3e50c602.1c94ca","name":"","pauseType":"delay","timeout":"750","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":870,"y":1200,"wires":[["c59c61a1.b8c13"]]},{"id":"247acafc.6ac866","type":"yeelight-compat-hue-out","z":"3e50c602.1c94ca","name":"","server":"1b82c79a.0adf18","x":1210,"y":1120,"wires":[]},{"id":"4f47c7f1.744b9","type":"function","z":"3e50c602.1c94ca","name":"Inverse State","func":"msg.payload = flow.get('pow');\nif (msg.payload===true) msg.payload='{\"on\": false}';\nelse msg.payload='{\"on\": true}';\nreturn msg;","outputs":1,"noerr":0,"x":670,"y":1200,"wires":[["106de578.09a63b","247acafc.6ac866","d2d308bf.83c38"]]},{"id":"67f02d96.dfef44","type":"function","z":"3e50c602.1c94ca","name":"Set State Flow","func":"//send the state on the flow\nvar onState = msg.payload.state.on;\nflow.set('pow',onState);","outputs":1,"noerr":0,"x":760,"y":1060,"wires":[[]]},{"id":"d2d308bf.83c38","type":"debug","z":"3e50c602.1c94ca","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1150,"y":1300,"wires":[]},{"id":"1b82c79a.0adf18","type":"yeelight-compat-hue-config","z":"","hostname":"192.168.0.34","port":"55443","name":"Smart Bulb RGBW"}]

If someone can help I will be greatfull :kissing_smiling_eyes:

i haven’t imported your flow, but from a quick look you appear to have the true / false as strings (they are surrounded with quotes) rather than boolean true false
If you are using a function try googling javascript boolean

if you are using a change node change the type from A/Z to boolean

@ukmoose ose
I know but this is working in the fist case so why would it not works in the second ?
My flow take inspiration of this exemple :
https://randomnerdtutorials.com/node-red-with-xiaomi-mijia-bedside-lamp/

In this tutorial when they switch the state they also used string instead of boolean
2019-01-13_14-24-02

So i try an another solution with removing the ""
but it still doesn't work :confused:

13/01/2019 à 14:25:52[node: 65dda72c.93408](http://192.168.0.18:1880/#)
msg.payload : Object

{ on: false }

13/01/2019 à 14:25:53[node: 65dda72c.93408](http://192.168.0.18:1880/#)
msg.payload : Object

{ on: false }

My guess is that the issue is related to the outer quotes, not to the inner quotes of the properties. Looks like the Yeelight node expects to receive an object to on its input. If you send like below you are sending a string to the node.

'{"on": false}'

The picture you attached seems to confirm the above. It shows that in the demo flow when you click on the button an object is generated. Note the symbols { } in front of '{"on": false}'

See this part of the node documentation:

r-01

They clearly state that msg.payload must be an object. You can see that in the inject node in the picture they are injecting an object, not a string.

I suggest to revise all your function nodes and test by changing strings by objects.

Edit: I can´t test my assumption since I don´t have a Yeelight. Also I have not checked your flow to see if there could be a glitch in the logic.

I just had a look in your flow. There is something I don't understand in the second flow (I have not checked the first one as a matter of fact).

r-02

The function Inverse State will test a flow variable pow for true / false and will output a string in the form "on" : false or "on" : true. Then a delay node will retain the msg for 750 ms. Now comes the issue. The function Get Back Stage is testing msg.payload for true or false. The issue is that msg.payload is no longer a boolean. At that point it will be a string in the form "on" : false or "on" : true. The end result is that the if statement in your second function wil always return false, no matter what. I understand you should revise the logic in the second function. Probably you want to update the flow variable pow in the first function and then test this variable again in the second function.

This is an example of a flow that performs the logic for your use case. It could be a reference for troubleshooting yours.

r-03

[{"id":"7553dd8f.e202a4","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"944f67f.9892598","type":"function","z":"7553dd8f.e202a4","name":"Get Back State","func":"let pow = flow.get('pow');\npow = !pow;\nmsg.payload.on = pow;\nflow.set('pow', pow)\nreturn msg;","outputs":1,"noerr":0,"x":780,"y":300,"wires":[["b598189e.854758"]]},{"id":"9557b5d2.ebe898","type":"inject","z":"7553dd8f.e202a4","name":"Notification","topic":"","payload":"{}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":300,"wires":[["48b65c02.0b8474"]]},{"id":"dd4bd082.d46e3","type":"delay","z":"7553dd8f.e202a4","name":"","pauseType":"delay","timeout":"750","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":570,"y":300,"wires":[["944f67f.9892598"]]},{"id":"48b65c02.0b8474","type":"function","z":"7553dd8f.e202a4","name":"Inverse State","func":"let pow = flow.get('pow');\npow = !pow;\nmsg.payload.on = pow;\nflow.set('pow', pow)\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":300,"wires":[["dd4bd082.d46e3","b233564f.eaece8"]]},{"id":"b233564f.eaece8","type":"debug","z":"7553dd8f.e202a4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":530,"y":380,"wires":[]},{"id":"b598189e.854758","type":"debug","z":"7553dd8f.e202a4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":970,"y":300,"wires":[]},{"id":"f92fbbfd.10bde8","type":"function","z":"7553dd8f.e202a4","name":"Set State Flow","func":"var onState = msg.payload;\nflow.set('pow',onState);\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":160,"wires":[["589f14e.2eabcec"]]},{"id":"1224eabe.14ba85","type":"inject","z":"7553dd8f.e202a4","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":140,"wires":[["f92fbbfd.10bde8"]]},{"id":"b13750b4.c7b19","type":"inject","z":"7553dd8f.e202a4","name":"","topic":"","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":200,"wires":[["f92fbbfd.10bde8"]]},{"id":"589f14e.2eabcec","type":"debug","z":"7553dd8f.e202a4","name":"SET Flow","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":520,"y":160,"wires":[]}]

Thanks you for the attention you pay on my work @Andrei !
I have try your flow but they are sometimes misfunctionnement ! I think we would'nt resolve this problem it probably came of the ping of the server because i'm far away from my WI-Fi router.

Anyway the flow that work the best iwas the first I had created, here it is :

[{"id":"4d78e92d.1362c8","type":"function","z":"3e50c602.1c94ca","name":"inverse power","func":"msg.payload = flow.get('pow');\nif (msg.payload===false) msg.payload='{\"on\": true}';\nelse msg.payload='{\"on\": false}';\nreturn msg;","outputs":1,"noerr":0,"x":1100,"y":680,"wires":[["d9fd4bd7.12fd78","4564cfa3.10991"]]},{"id":"6ed638a.9d06748","type":"switch","z":"3e50c602.1c94ca","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":550,"y":660,"wires":[["92531e4b.a896c","cdc69864.95eed8"]]},{"id":"527d4ba4.18a0bc","type":"function","z":"3e50c602.1c94ca","name":"False","func":"return {payload : false};","outputs":1,"noerr":0,"x":410,"y":620,"wires":[["6ed638a.9d06748"]]},{"id":"db123eec.9cc358","type":"inject","z":"3e50c602.1c94ca","name":"Turn true","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":700,"wires":[["6ed638a.9d06748"]]},{"id":"92531e4b.a896c","type":"yeelight-compat-hue-state","z":"3e50c602.1c94ca","name":"Get State","server":"1b82c79a.0adf18","x":530,"y":500,"wires":[["b079f31a.68535","527d4ba4.18a0bc"]]},{"id":"30bd23aa.abe554","type":"delay","z":"3e50c602.1c94ca","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":920,"y":680,"wires":[["4d78e92d.1362c8"]]},{"id":"d9fd4bd7.12fd78","type":"yeelight-compat-hue-out","z":"3e50c602.1c94ca","name":"","server":"1b82c79a.0adf18","x":1010,"y":880,"wires":[]},{"id":"cdc69864.95eed8","type":"function","z":"3e50c602.1c94ca","name":"get power","func":"msg.payload = flow.get('pow');\nif (msg.payload===true) msg.payload='{\"on\": false}';\nelse msg.payload='{\"on\": true}';\nreturn msg;","outputs":1,"noerr":0,"x":740,"y":680,"wires":[["30bd23aa.abe554","d9fd4bd7.12fd78","4564cfa3.10991"]]},{"id":"4564cfa3.10991","type":"debug","z":"3e50c602.1c94ca","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1130,"y":800,"wires":[]},{"id":"b079f31a.68535","type":"function","z":"3e50c602.1c94ca","name":"Set State Flow","func":"var onState = msg.payload.state.on;\nflow.set('pow',onState);","outputs":1,"noerr":0,"x":800,"y":500,"wires":[[]]},{"id":"1b82c79a.0adf18","type":"yeelight-compat-hue-config","z":"","hostname":"192.168.0.34","port":"55443","name":"Smart Bulb RGBW"}]

Sure enough, the flow you just posted is better than the original post.

One important difference is in the code of the second function.

Original Post:

if(msg.payload===false) msg.payload='{"on": true}';
else msg.payload='{"on": false}';
return msg;

Latest Post

msg.payload = flow.get('pow');
if (msg.payload===false) msg.payload='{"on": true}';
else msg.payload='{"on": false}';
return msg;

In the second case you are reading to msg.payload the flow variable pow. This flow variable holds a boolean value so the if statement will make sense. The way it was before, without the line msg.payload = flow.get('pow'); results that the if statement will always return false.

Ok I have understand my mistake :sweat:


The Yeelight State Block actualise himself at every switch of the lamp. As i was working on the same page with different flow I could'nt read properly the state of the lamp...

So i'm using your solution just with a little delay before getting the Lamp's state :grinning:

Thank you for your patience and help Andrei :wink:

1 Like