Weird Function Output

Hi. I wrote a function to compare temperature values. This function was connected to a trigger, and trigger was connected to a button. I learned that this part must be running at all times, without the button press. So, I put a timestamp before it. Now, I sometimes read values like these:

{ payload: 1595856943673, topic: "", _msgid: "661b8566.10c17c" }
7/27/2020, 4:35:47 PMnode: 7be3371.28d15c8
msg : Object
{ payload: 29, topic: "", _msgid: "8dfcb019.41d8a" }
7/27/2020, 4:35:51 PMnode: 7be3371.28d15c8
msg : Object
{ payload: 29, topic: "",

Now, it kept repeating reading that huge value for 10+ times. This is making the system use PID in a wrong way. How can I solve this? Should I just add a if statement where the value is below 50 or something, or is there a better way to run something all the time without any interaction from the user?

Here is the inject node in timestamp mode, and the function I wrote:

[{"id":"f27ba700.882368","type":"inject","z":"4cdd06f6.faf528","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"4","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":490,"y":380,"wires":[["ed704f4c.f27a5"]]},{"id":"ed704f4c.f27a5","type":"function","z":"4cdd06f6.faf528","name":"","func":"var k1 = global.get('k1');\nvar k2 = global.get('k2');\nvar k3 = global.get('k3');\n\nif(k1>k2 && k1>k3)\n{\n    msg.payload = k1;\n}\nif(k2>k1 && k2>k3)\n{\n    msg.payload = k2;\n}\nif(k3>k1 && k3>k2)\n{\n    msg.payload = k3;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":660,"y":380,"wires":[["e5102467.06b418","7be3371.28d15c8"]]}]

Those k1, k2, k3 values are from temperature sensors.

Can you explain what you are actually trying to do? Why don't you just feed in the temperatures directly rather than going through context variables (which should be avoided unless there is a good reason for using them)?

When you do it like you have said, it doesn't work properly. Imagine that sensor1 is above 40 degress, and I want to keep it at 35. sensor2 and sensor3 are less than 35. So, PID starts to work as expected after seeing that sensor1 is 40 degress. However, it stops in less than a second, because sensor 2 is less than 35, which stops the PID. Multiple inputs don't work, even if one of them in on the other side of the condition. So, I am trying to use only the highest value among all sensor to solve this problem. This is now there the fault is. It was working perfectly fine when I connected an on/off switch to a trigger that triggers this function every 9 seconds. I learned that the PID part must work at all times, even when the system is off (not the Pi, just the GUI side).

Do you mean you want to control using the highest of the three sensors? How often are there new temperature values from the sensors?

Yes. I want to control it with only the highest. They are all very close in the project, and the liquid will cool down all areas. They are all being read every 9 seconds, but this is not the issue. I just need timestamp to activate the function every 4 or 9 seconds. Doesn't really matter. Getting those huge values is the only problem here. How can I fix it? They come from the timestamp, because they weren't there when I was activating the function with an on/off switch, connected to trigger. May I should put a trigger in between. Haven't tried that.

Do it like this. The inject nodes are to simulate your sensors. Feed it direct from the sensors (or from MQTT if you are feeding your sensors into MQTT). Don't use global context unless there is a good reason. It causes just the sort of problems that you are finding. Make sure the sensor messages have separate topics (which likely they already do) and in the function node replace sensor_1 2 and 3 with those topics.

image

[{"id":"b0e3bea4.b86b5","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor_1","payload":"20","payloadType":"num","x":200,"y":1680,"wires":[["f80fd5b6.3af4d8"]]},{"id":"9bf273cc.a35668","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor_1","payload":"23","payloadType":"num","x":210,"y":1720,"wires":[["f80fd5b6.3af4d8"]]},{"id":"82957b35.4720e8","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor_2","payload":"19","payloadType":"num","x":190,"y":1800,"wires":[["f80fd5b6.3af4d8"]]},{"id":"a6dcd753.a4d04","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor_2","payload":"25","payloadType":"num","x":200,"y":1840,"wires":[["f80fd5b6.3af4d8"]]},{"id":"3a19feb1.a28bca","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor_3","payload":"20","payloadType":"num","x":190,"y":1920,"wires":[["f80fd5b6.3af4d8"]]},{"id":"6a52b9dd.ebc5a","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor_3","payload":"24","payloadType":"num","x":200,"y":1960,"wires":[["f80fd5b6.3af4d8"]]},{"id":"f80fd5b6.3af4d8","type":"join","z":"bdd7be38.d3b55","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"1","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":430,"y":1820,"wires":[["bdc68695.d0f348"]]},{"id":"5b1ee63e.8e8308","type":"debug","z":"bdd7be38.d3b55","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":530,"y":1920,"wires":[]},{"id":"bdc68695.d0f348","type":"function","z":"bdd7be38.d3b55","name":"Max","func":"let v1 = msg.payload.sensor_1 || -100\nlet v2 = msg.payload.sensor_2 || -100\nlet v3 = msg.payload.sensor_3 || -100\n\nmsg.payload = Math.max(v1,v2,v3)\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":550,"y":1820,"wires":[["5b1ee63e.8e8308"]]}]

Join didn't work. Tried it before. I'll try it with your flow again.

You didn't do it right then.

2 Likes

Here, I changed the msg.topic to msg.id after the error. Still got the same error type. I am only feeding it with 3 sensors.

7/27/2020, 6:39:44 PMnode: dd797303.e3d45
msg : string[63]
"Message missing key property 'msg.topic' - cannot add to object"
7/27/2020, 6:39:44 PMnode: dd797303.e3d45
msg : string[63]
"Message missing key property 'msg.topic' - cannot add to object"
7/27/2020, 6:39:45 PMnode: dd797303.e3d45
msg : string[63]
"Message missing key property 'msg.topic' - cannot add to object"
7/27/2020, 6:39:58 PMnode: dd797303.e3d45
msg : string[60]
"Message missing key property 'msg.id' - cannot add to object"
7/27/2020, 6:39:58 PMnode: dd797303.e3d45
msg : string[60]
"Message missing key property 'msg.id' - cannot add to object"
7/27/2020, 6:39:58 PMnode: dd797303.e3d45
msg : string[60]
"Message missing key property 'msg.id' - cannot add to object"

Edit: Here is the result when I change it to msg.payload:

7/27/2020, 6:42:11 PMnode: 3dc376e7.b4377a
msg.payload : number
-100
7/27/2020, 6:42:11 PMnode: 3dc376e7.b4377a
msg.payload : number
-100
7/27/2020, 6:42:11 PMnode: 3dc376e7.b4377a
msg.payload : number
-100

I don't understand what you mean. The error means that the messages coming in have not got a topic set. You need to make sure that they have topics to identify which sensor is which.
Put a debug node showing the messages going into the join node and make sure they have topics set.

I set their topics, didn't work. Getting the same thing as the above, where I added in "Edit" part.

Post the flow you are using from sensors to the pid node.

They are not fully connected at the moment, since I am just reading from debug node. Here is the flow:

[{"id":"f9fb7204.76419","type":"sensor-ds18b20","z":"4cdd06f6.faf528","name":"Kazan","topic":"","sensorid":"28-012019d65680","timer":"9","repeat":true,"x":70,"y":180,"wires":[["6562974d.0be428","3455b915.976f06"]]},{"id":"69a8d632.400978","type":"sensor-ds18b20","z":"4cdd06f6.faf528","name":"Kask-1","topic":"","sensorid":"28-0300a2790a56","timer":"9","repeat":true,"x":80,"y":220,"wires":[["745a7d7d.f55c44","d307a3d8.c8de4","dd797303.e3d45"]]},{"id":"ef5170fe.15e88","type":"sensor-ds18b20","z":"4cdd06f6.faf528","name":"Kask-2","topic":"","sensorid":"28-0300a279f0d6","timer":"9","repeat":true,"x":80,"y":260,"wires":[["33cb2220.4a65de","67e42901.f52fc8","dd797303.e3d45"]]},{"id":"b5e46c66.852f6","type":"sensor-ds18b20","z":"4cdd06f6.faf528","name":"Kask-3","topic":"","sensorid":"28-0300a279dceb","timer":"9","repeat":true,"x":80,"y":300,"wires":[["92fa6a95.69fd38","c15f42eb.b7c57","dd797303.e3d45"]]},{"id":"dd797303.e3d45","type":"join","z":"4cdd06f6.faf528","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"1","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":930,"y":620,"wires":[["75b22d2a.9aff04"]]},{"id":"75b22d2a.9aff04","type":"function","z":"4cdd06f6.faf528","name":"Max","func":"let v1 = msg.payload.sensor_1 || -100\nlet v2 = msg.payload.sensor_2 || -100\nlet v3 = msg.payload.sensor_3 || -100\n\nmsg.payload = Math.max(v1,v2,v3)\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1050,"y":620,"wires":[["3dc376e7.b4377a"]]},{"id":"3dc376e7.b4377a","type":"debug","z":"4cdd06f6.faf528","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1030,"y":720,"wires":[]}]

Edit: Again, I did not have this problem before. I was still using global values. Changing from button to timestamp caused this to happen, I believe.

So what do you see if you add a debug node showing what is coming from the sensor nodes?

7/27/2020, 6:50:32 PMnode: 3ff39960.d6ec96
Kask-3 : msg.payload : number
27.3

Is there a way to imitate an on/off switch, without using one? I just need this. It was working perfectly fine before.

Edit: Or, I could somehow give "1" to a trigger, for infinite amount of time (as if a switch was pressed), then the trigger would trigger my function. This method had no problems. I just need to separate it from the start/stop button on the GUI, and make it work all the time.

Attach a debug node connected to all three sensor nodes and another on the output of the Join node. Screenshot what you see. Give the debug nodes names.
Edit, corrected text above

You haven't edited the function node and put in your topics instead of sensor_1, 2 and 3. Hence the -100 values.

[Edit] Are those minus signs in the topics? If so that it not generally a good idea as you have to allow for that in any javascript you write, otherwise it interprets them as minus signs. So you will have to use something like, for example
let v1 = msg.payload["Kask-1"] || -100

I get all 3 at the same time. Like this:


de
7/27/2020, 7:06:58 PMnode: colin's fnc
kask_2 : msg.payload : number
26.6
7/27/2020, 7:06:58 PMnode: colin's fnc
kask_1 : msg.payload : number
27.4
7/27/2020, 7:06:58 PMnode: colin's fnc
kask_3 : msg.payload : number
31.4