How to change output?

I'm beginner in "Node-red", can you tell me what I'm doing wrong?
I have output like this

01.09.2020, 17:13:21node: 1acab143.6805af
zigbee2mqtt/0xec1bbdfffe6dff16 : msg.payload : Object
object
update_available: true
state: "OFF"
linkquality: 76
brightness: 254
color_temp: 254
color: object
x: 0.4599
y: 0.4106
  1. I need get each output separately and in json format.
  1. and "payload.state" should be changed from this "OFF" forms to this {"state": "OFF"} and allso be in json format.
    But, it is doesn't want to change at all! see screen

    my Initial flow https://pastebin.com/DhcyyDEy

Whilst waiting for detailed help I suggest you work through the node red essentials videos, that will give a lot of useful information and may well allow you to answer the question yourself.

Where you use this msg1.payload = msg.payload.state;
try using msg1.payload.state = msg.payload.state;

it writes:
"TypeError: Cannot set property 'state' of undefined"

I found a solution, not as pretty as I want, but it works!

Now, I want to write the code so that I would receive a message only when the status has changed, not constantly!

p=msg.payload; 
var flag = flow.get('flag') || "";  
node.log(typeof p);
msg.payload=p.state;

if(msg.payload == "ON" && flag != "ON") { 
    msg.payload = {"state":"ON"}; 
    flow.set('flag',"ON"); 
} 
else(msg.payload == "OFF" && flag != "OFF");{
    msg.payload = {"state":"OFF"}; 
    flow.set('flag',"OFF"); 
} 
return msg

But, my condition is not met! it write to me state all time, don't understand where I did mistake?!?!

Try this, change these lines:

var flag = flow.get('flag') || "";  
node.log(typeof p);
msg.payload=p.state;

to

var p = {}
p.status=msg.payload.status; 
msg.payload = p;

Msg.payload will now be an object {status: "OFF"} so in your code you will have to use msg.payload.status

I redid it according to your instructions.

p=msg.payload; 
var p = {};  
var flag = flow.get('flag') || "";
p.status=msg.payload.status;
msg.payload=p;

if(p.status == "ON" && flag != "ON") { 
    msg.payload = {"state":"ON"}; 
    flow.set('flag',"ON"); 
} 
else(p.status == "OFF" && flag != "OFF");{
    msg.payload = {"state":"OFF"}; 
    flow.set('flag',"OFF"); 
} 
return msg

But that doesn't work either. And all time write state: "OFF"
Even when it turned on!
The condition is not met, for some reason!

My mistake, I should have said get rid of the four lines

p=msg.payload; 
var flag = flow.get('flag') || "";  
node.log(typeof p);
msg.payload=p.state;

You also don't need the msg.payload = {"state":"ON"}; and msg.payload = {"state":"OFF"}; ' since you have already set msg.payload=p;` which is the state.

In addition,

  • in your IF statement you have a test in the else - you need to use else if
  • in this code
else(p.status == "OFF" && flag != "OFF");{
    msg.payload = {"state":"OFF"}; 
    flow.set('flag',"OFF"); 
} 

the semicolon ends the if statement so the next two lines are always executed.

Does not work! Or I misunderstand you?

p=msg.payload; 
var flag = flow.get('flag') || "";  
node.log(typeof p);
msg.payload=p.state;

if(msg.payload == "ON" && flag != "ON") { 
    msg.payload = {"state":"ON"}; 
    flow.set('flag',"ON"); 
} 
else(msg.payload == "OFF" && flag != "OFF");{
    msg.payload = {"state":"OFF"}; 
    flow.set('flag',"OFF"); 
} 
return msg

as I said previously, in your IF statement you have a test in the else - you need to use else if so
else(msg.payload == "OFF" && flag != "OFF");{
needs to be
else if (msg.payload == "OFF" && flag != "OFF");{
in addition that line has a semicolon (;) after the condition which ends the if statement. It needs to be removed so you have
else if (msg.payload == "OFF" && flag != "OFF") {

also you had correctly changed the if statement to use p.status but you changed it back to test to use msg.payload. Why did you do that? With the statement msg.payload=p.state; msg.payload is now an object so if you want to test using the msg.payload you need to test using msg.payload.status and you do not need the assignments msg.payload = {"state":"ON"}; or msg.payload = {"state":"OFF"};

Object programming it is my weak side! And I don't understand why the checking of flag doesn't work!? it should write in debug window only then the status has changed!
And it writes to me all the time, which indicates that the condition if(msg.payload == "ON" && flag != "ON") { does not work!

My current state of the code.

p=msg.payload; 
var flag = flow.get('flag') || "";  
node.log(typeof p);
msg.payload=p.state;

if(msg.payload == "ON" && flag != "ON") { 
    msg.payload.status; 
    flow.set('flag',"ON"); 
} 
else if (msg.payload == "OFF" && flag != "OFF") {
    msg.payload.status; 
    flow.set('flag',"OFF"); 
} 
return msg

This isn't object programming.

Import this small flow so you can see what I am talking about. I have commented the function node to explain what is happening.

[{"id":"19a4f700.d59c91","type":"function","z":"94b68392.acdaf8","name":"","func":"// initilize flag to he contents of the flow variable\n// or as an empty string\nvar flag = flow.get('flag') || \"\";\n\n//initilize 'p' as an object\nvar p = {};  \n\n// set p.status to the value of msg.payload.status. This means it\n// msg.payload.status = {\"status\": \"OFF\"} then \n// p.status will be {\"status\": \"OFF\"}\np.status=msg.payload.status;\n\n// now set msg.payload to just the contents of p.status so all the \n// other parts of teh original paload object will be gone and \n// msg.payload will be {\"status\": \"OFF\"}\nmsg.payload=p;\n\n// Display the contents of p.status and msg.payload\nnode.warn(\"p.status=\"+JSON.stringify(p))\nnode.warn(\"msg.payload=\"+JSON.stringify(msg.payload))\n\n//test p.status (or you could test msg.payload.status)\nif (p.status == \"ON\" && flag != \"ON\") { \n    node.warn(\"in ON\")  // show we are in the 'on' code\n    flow.set('flag',\"ON\"); \n} \nelse if (p.status == \"OFF\" && flag != \"OFF\") {\n    // show we are in teh off code\n    node.warn(\"in OFF\")\n    flow.set('flag',\"OFF\"); \n} \n\n// return the msg\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","x":390,"y":380,"wires":[["92d34a60.e2c08"]]},{"id":"92d34a60.e2c08","type":"debug","z":"94b68392.acdaf8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":590,"y":380,"wires":[]},{"id":"81e79f1f.769418","type":"inject","z":"94b68392.acdaf8","name":"ON","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"update_available\":true,\"status\":\"ON\",\"linkquality\":76,\"brightness\":254,\"color_temp\":254,\"color\":{\"x\":0.4599,\"y\":0.4106}}","payloadType":"json","x":170,"y":380,"wires":[["19a4f700.d59c91","793f50f0.7f8e8"]]},{"id":"b2d4c0ca.782b7","type":"inject","z":"94b68392.acdaf8","name":"OFF","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"update_available\":true,\"status\":\"OFF\",\"linkquality\":76,\"brightness\":254,\"color_temp\":254,\"color\":{\"x\":0.4599,\"y\":0.4106}}","payloadType":"json","x":170,"y":440,"wires":[["19a4f700.d59c91","793f50f0.7f8e8"]]},{"id":"793f50f0.7f8e8","type":"debug","z":"94b68392.acdaf8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":390,"y":440,"wires":[]}]

Thank you for explained in great detail!
But, your code also works like mine (Not working)
I'm trying to make that if the status has not changed, then do not send a message. Your code like mine code it ignores the flag ... And all the time it sends a message to debug the window.

So in english you want
if msg.payload.status is the same as flow.status ignore this msg but display a debug message
if msg.payload.ststus is NOT the same as flow.status then

  • set flow.status to the new status
  • return msg.payload with the contents of what msg.payload.status was

That about right?

If my assumption was correct then your original if statements were incorrect. Here is the flow with a corrected version and a second flow showinng how you could do it without a function node.

[{"id":"15069f84.a068c8","type":"function","z":"94b68392.acdaf8","name":"","func":"// initilize flag to he contents of the flow variable\n// or as an empty string\nvar flag = flow.get('flag') || \"\";\n//node.warn(\"flag=\"+flag)  //uncomment to see contents of 'flag'\n\n//initilize 'p' as an object\nvar p = {};  \n\n// set p.status to the value of msg.payload.status. This means it\n// msg.payload.status = {\"status\": \"OFF\"} then \n// p.status will be {\"status\": \"OFF\"}\np.status=msg.payload.status;\n\n// now set msg.payload to just the contents of p.status so all the \n// other parts of teh original paload object will be gone and \n// msg.payload will be {\"status\": \"OFF\"}\nmsg.payload=p;\n\n// Display the contents of p.status and msg.payload\n//node.warn(\"p.status=\"+JSON.stringify(p))\n//node.warn(\"msg.payload=\"+JSON.stringify(msg.payload))\n\n//test p.status (or you could test msg.payload.status)\nif (p.status == flag ) { \n    node.warn(\"No change in status\")  // show 'no change debug msg flow.set('flag',p.status); \n    return // exit flow without returning anything\n    \n} \nelse {  // the status has changed, so update flow.flag\n        // with the new statusu and return the msg\n    flow.set('flag',p.status) \n} \n\n// return the msg\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":580,"wires":[["6a376694.7e5d5"]]},{"id":"6a376694.7e5d5","type":"debug","z":"94b68392.acdaf8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":560,"y":580,"wires":[]},{"id":"40268cde.710c54","type":"inject","z":"94b68392.acdaf8","name":"ON","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"update_available\":true,\"status\":\"ON\",\"linkquality\":76,\"brightness\":254,\"color_temp\":254,\"color\":{\"x\":0.4599,\"y\":0.4106}}","payloadType":"json","x":140,"y":580,"wires":[["15069f84.a068c8","cd498fad.d0b9b"]]},{"id":"9f62723c.7523f8","type":"inject","z":"94b68392.acdaf8","name":"OFF","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"update_available\":true,\"status\":\"OFF\",\"linkquality\":76,\"brightness\":254,\"color_temp\":254,\"color\":{\"x\":0.4599,\"y\":0.4106}}","payloadType":"json","x":140,"y":640,"wires":[["15069f84.a068c8","cd498fad.d0b9b"]]},{"id":"cd498fad.d0b9b","type":"debug","z":"94b68392.acdaf8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":360,"y":640,"wires":[]},{"id":"5f552c7d.0f0b04","type":"inject","z":"94b68392.acdaf8","name":"ON","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"update_available\":true,\"status\":\"ON\",\"linkquality\":76,\"brightness\":254,\"color_temp\":254,\"color\":{\"x\":0.4599,\"y\":0.4106}}","payloadType":"json","x":130,"y":740,"wires":[["d149731c.7b49f"]]},{"id":"f0e9018f.11f94","type":"inject","z":"94b68392.acdaf8","name":"OFF","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"update_available\":true,\"status\":\"OFF\",\"linkquality\":76,\"brightness\":254,\"color_temp\":254,\"color\":{\"x\":0.4599,\"y\":0.4106}}","payloadType":"json","x":130,"y":780,"wires":[["d149731c.7b49f"]]},{"id":"d149731c.7b49f","type":"switch","z":"94b68392.acdaf8","name":"Check Flag vrs status","property":"flag","propertyType":"flow","rules":[{"t":"null"},{"t":"neq","v":"payload.status","vt":"msg"},{"t":"else"}],"checkall":"false","repair":false,"outputs":3,"x":320,"y":760,"wires":[["b62adb39.0ae9a"],["b62adb39.0ae9a"],["acd6481b.a2c018"]]},{"id":"acd6481b.a2c018","type":"change","z":"94b68392.acdaf8","name":"build a debug message","rules":[{"t":"set","p":"payload","pt":"msg","to":"no change in status","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":570,"y":780,"wires":[["f09866c7.d4511"]]},{"id":"f09866c7.d4511","type":"debug","z":"94b68392.acdaf8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":850,"y":780,"wires":[]},{"id":"b62adb39.0ae9a","type":"change","z":"94b68392.acdaf8","name":"update flow.flag and msg.payload","rules":[{"t":"set","p":"flag","pt":"flow","to":"payload.status","tot":"msg"},{"t":"move","p":"payload.status","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":740,"wires":[["735e0ec3.9275e"]]},{"id":"735e0ec3.9275e","type":"debug","z":"94b68392.acdaf8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":850,"y":740,"wires":[]}]
1 Like

Thank you very much!!!
The second flow it is what i wanted! Sorry for my English!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.