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

For function timer on Events: state node being incorrectly reset. #277

Closed
crkochan opened this issue Oct 11, 2020 · 4 comments
Closed

For function timer on Events: state node being incorrectly reset. #277

crkochan opened this issue Oct 11, 2020 · 4 comments
Labels
Type: Bug Something isn't working

Comments

@crkochan
Copy link

Describe the bug

I have a chain setup to perform actions when the wattage on a computer plug rises above a certain threshold for a given amount of time. Prior to v0.27.0, I did by setting an appropriate "If State" parameter on the events: state node and piping the 'If State' is true output to a delay node. After v0.27.0, I switched to using the new for condition on the events: state node, however I found that I was not getting the same functionality that I previously had.

What seems to be happening is that the for condition timer is being reset every time the truthiness of the if state is being evaluated as state value changes occur, even if the if state condition remains true.

To Reproduce

Steps to reproduce the behavior:

  1. Create an events: state node for an entity that reports a numerical value, such as an input_number entity.
  2. Set the if state to a > $threshold configuration, for example > 10
  3. Set the for function to a value appropriate for debugging, say 5 minutes.
  4. Deploy node.
  5. Set input_number entity to be above the threshold, say 12 if you used the threshold from step 2.
  6. Observe that the events: state node shows waiting for 5 minutes: <timestamp>
  7. Set the input_number entity to another value that is still above the threshold.
  8. Observe that the events: state node still shows waiting for 5 minutes: <timestamp>, but that the timestamp has changed. and is now five minutes from the time the input_number entity was last updated, indicating that it has been reset even though the if state was not false.

Expected behavior

The behavior I'm expecting is that the timer would continue counting down from the point at which the if state originally became true and would not be reset in the event of a state change that still evaluated as true.

As it stands now, for nodes that evaluate a sensor that monitors wattage, where the value can change quite often, and still remain above the if state threshold, the node will never issue a message unless a timer value is chosen that is less than the refresh rate of the sensor, which would be sub-optimal.

Screenshots

An events: state node configured to monitor a wattage sensor
image

The node waits to emit a message for five minutes when the sensor value is above threshold.
image

The time stamp on the node status continues advancing as the wattage sensor continues updating, even though the reported value continues to be above threshold.
image

Example Flow

[{"id":"155602cc.0e551d","type":"server-state-changed","z":"394bac4e.8eac34","name":"PC load > 400 watts","server":"9c0448ad.8b94c8","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.computer_plug_power","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","haltifstate":"400","halt_if_type":"num","halt_if_compare":"gt","outputs":2,"output_only_on_state_change":false,"for":"5","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":170,"y":1400,"wires":[["4b6301e3.fffd4"],[]]},{"id":"4b6301e3.fffd4","type":"api-call-service","z":"394bac4e.8eac34","name":"","server":"9c0448ad.8b94c8","version":1,"debugenabled":false,"service_domain":"script","service":"do_nifty_thing","entityId":"","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":460,"y":1400,"wires":[[]]},{"id":"9c0448ad.8b94c8","type":"server","z":"","name":"Home Assistant"}]

Environment (please complete the following information):

  • Node Red Version: 1.1.3
  • Node.js Version: 12.18.4
  • NR Home Assistant Plugin Version: 0.27.1
  • Is Node Red running in Docker: Yes (HA addon by Frenck)

Other (please complete the following information):

  • Have you searched previous issues for duplicates?: Yes.

Additional context

None.

@zachowj zachowj added the Type: Bug Something isn't working label Oct 11, 2020
@zachowj
Copy link
Owner

zachowj commented Oct 11, 2020

How should the timer logic be handled after the node has been triggered for being greater than 400 for 5 minutes?

  • Restart a new timer if the condition is still true
  • Don't restart a new timer until the condition has been false and then true again

I'll probably have to look at how HA handles that to keep them similar.

@crkochan
Copy link
Author

I see what you're getting at, and I also didn't know how HA would handle a similar automation, so I ran some tests.

I created an input_number in HA's helpers panel with a range of 0 to 100, and setup a simple automation around it.


Triggers

Trigger type: Numeric state
Entity: input_number.testing
Above: 20
For: 00:00:10

Actions

Action type: Call service
Service: notify.my_iphone
Service data:
title: Some
message: message


Basically, if I set the input_number to a value above 20 and leave it there for ten seconds, I get a notification on my phone.

I then proceeded to test the automation in the various execution modes (Single, Restart, Queued, Parallel). In all configurations, if I set value above 20, I'd get the notification ~10 seconds later. If I then set the value to another setting above the threshold, I would not get a notification. If I set it below the threshold, and then set it back above, I would then get a notification.

Based on this, it seems as though the automation engine in HA conforms to the second bullet point, in that a new timer is not started until the condition is false and subsequently becomes true again.

The only conditions under which I got a notification after setting the input_number value to an above threshold number from and above threshold number, was after having made a change to the automation and hitting the save button.

If you're interested in my actual real-world chains, they're included below.

[{"id":"7d48e461.b7b2ec","type":"server-state-changed","z":"394bac4e.8eac34","name":"PC load > 400 watts","server":"9c0448ad.8b94c8","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.computer_plug_power","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","haltifstate":"400","halt_if_type":"num","halt_if_compare":"gt","outputs":2,"output_only_on_state_change":false,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":150,"y":1060,"wires":[["f5137115.426f4"],["28f5238f.d5383c","e05b5713.70ea28"]]},{"id":"de7cc2e6.3405c","type":"api-current-state","z":"394bac4e.8eac34","name":"If 3F HVAC is cooling","server":"9c0448ad.8b94c8","version":1,"outputs":2,"halt_if":"cool","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"climate.l5_007","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":780,"y":1060,"wires":[["b6a4ed80.21f54"],[]]},{"id":"b6a4ed80.21f54","type":"switch","z":"394bac4e.8eac34","name":"...and temp is > 72","property":"data.attributes.temperature","propertyType":"msg","rules":[{"t":"gt","v":"72","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":990,"y":1060,"wires":[["21407d18.9fbd62"]]},{"id":"f4a740b4.5492a","type":"api-call-service","z":"394bac4e.8eac34","name":"Set temp to 72","server":"9c0448ad.8b94c8","version":1,"debugenabled":false,"service_domain":"climate","service":"set_temperature","entityId":"climate.l5_007","data":"{\"temperature\":\"72\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1600,"y":1060,"wires":[["abe72224.bb235"]]},{"id":"77b0b185.5034c","type":"api-call-service","z":"394bac4e.8eac34","name":"Set temp & hvac_mode","server":"9c0448ad.8b94c8","version":1,"debugenabled":false,"service_domain":"climate","service":"set_temperature","entityId":"climate.l5_007","data":"{\"temperature\":\"{{data.temperature}}\",\"hvac_mode\":\"{{data.hvac_mode}}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1410,"y":1200,"wires":[["a6d8788d.2952a8"]]},{"id":"a2393d27.bbca4","type":"server-state-changed","z":"394bac4e.8eac34","name":"PC load < 400 watts","server":"9c0448ad.8b94c8","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.computer_plug_power","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","haltifstate":"400","halt_if_type":"num","halt_if_compare":"lt","outputs":2,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":150,"y":1200,"wires":[["e47752f3.84478"],["776af082.32a48"]]},{"id":"e47752f3.84478","type":"traffic","z":"394bac4e.8eac34","name":"","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":370,"y":1200,"wires":[["28f5238f.d5383c","cb2aebb9.66a2e8","834110f9.4374a"]]},{"id":"f5137115.426f4","type":"traffic","z":"394bac4e.8eac34","name":"","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":true,"differ":false,"x":370,"y":1060,"wires":[["80d3b8a9.5fe3a8","836123d6.09da6"]]},{"id":"80d3b8a9.5fe3a8","type":"change","z":"394bac4e.8eac34","name":"stop","rules":[{"t":"set","p":"payload","pt":"msg","to":"stop","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":1140,"wires":[["f5137115.426f4"]]},{"id":"cb2aebb9.66a2e8","type":"change","z":"394bac4e.8eac34","name":"stop","rules":[{"t":"set","p":"payload","pt":"msg","to":"stop","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":1280,"wires":[["e47752f3.84478"]]},{"id":"da0a527b.cff23","type":"change","z":"394bac4e.8eac34","name":"go","rules":[{"t":"set","p":"payload","pt":"msg","to":"go","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1030,"y":1140,"wires":[["e47752f3.84478"]]},{"id":"f1bb8c31.c581e","type":"comment","z":"394bac4e.8eac34","name":"Additional cooling based on PC load.","info":"If the load from the PC rises above 600 watts, indicating it's putting out a lot of heat, trigger changes in the HVAC mode.","x":200,"y":1020,"wires":[]},{"id":"28f5238f.d5383c","type":"change","z":"394bac4e.8eac34","name":"go","rules":[{"t":"set","p":"payload","pt":"msg","to":"go","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":1140,"wires":[["f5137115.426f4"]]},{"id":"61db51c6.7f808","type":"switch","z":"394bac4e.8eac34","name":"HVAC mode changed?","property":"data.hvac_mode","propertyType":"msg","rules":[{"t":"eq","v":"payload","vt":"msg"}],"checkall":"true","repair":false,"outputs":1,"x":1180,"y":1200,"wires":[["77b0b185.5034c"]]},{"id":"9f740613.304cb8","type":"api-current-state","z":"394bac4e.8eac34","name":"Get 3F HVAC state","server":"9c0448ad.8b94c8","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":true,"entity_id":"climate.l5_007","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":770,"y":1200,"wires":[["3770bead.d08012"]]},{"id":"21407d18.9fbd62","type":"api-current-state","z":"394bac4e.8eac34","name":"Get 3F HVAC data","server":"9c0448ad.8b94c8","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"climate.l5_007","state_type":"str","state_location":"","override_payload":"none","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":1190,"y":1060,"wires":[["4175214f.b4e8"]]},{"id":"4175214f.b4e8","type":"function","z":"394bac4e.8eac34","name":"Save hvac properties","func":"var entity = msg.data.entity_id\nvar hvac_mode = msg.data.state\nvar fan_mode = msg.data.attributes.fan_mode\nvar temperature = msg.data.attributes.temperature\nflow.set([\n    `${entity}-hvac_mode`, \n    `${entity}-fan_mode`, \n    `${entity}-temperature`\n    ], [\n        `${hvac_mode}`, \n        `${fan_mode}`, \n        `${temperature}`\n    ]\n);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1400,"y":1060,"wires":[["f4a740b4.5492a"]]},{"id":"3770bead.d08012","type":"function","z":"394bac4e.8eac34","name":"Get hvac properties","func":"var entity = msg.topic;\nvar hvac_mode = flow.get(`${entity}-hvac_mode`);\nvar fan_mode = flow.get(`${entity}-fan_mode`);\nvar temperature = flow.get(`${entity}-temperature`);\nmsg.data = {};\nmsg.data.entity_id = `${entity}`;\nmsg.data.hvac_mode = `${hvac_mode}`;\nmsg.data.fan_mode = `${fan_mode}`;\nmsg.data.temperature = `${temperature}`;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":970,"y":1200,"wires":[["61db51c6.7f808"]]},{"id":"a6d8788d.2952a8","type":"api-call-service","z":"394bac4e.8eac34","name":"Set fan_mode","server":"9c0448ad.8b94c8","version":1,"debugenabled":false,"service_domain":"climate","service":"set_fan_mode","entityId":"climate.l5_007","data":"{\"fan_mode\":\"{{data.fan_mode}}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1620,"y":1180,"wires":[[]]},{"id":"abe72224.bb235","type":"api-call-service","z":"394bac4e.8eac34","name":"Set fan to medium","server":"9c0448ad.8b94c8","version":1,"debugenabled":false,"service_domain":"climate","service":"set_fan_mode","entityId":"climate.l5_007","data":"{\"fan_mode\":\"med\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1530,"y":1120,"wires":[["da0a527b.cff23"]]},{"id":"836123d6.09da6","type":"delay","z":"394bac4e.8eac34","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":560,"y":1060,"wires":[["de7cc2e6.3405c","e05b5713.70ea28"]]},{"id":"834110f9.4374a","type":"delay","z":"394bac4e.8eac34","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":560,"y":1200,"wires":[["9f740613.304cb8","776af082.32a48"]]},{"id":"776af082.32a48","type":"change","z":"394bac4e.8eac34","name":"Reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":210,"y":1280,"wires":[["834110f9.4374a"]]},{"id":"e05b5713.70ea28","type":"change","z":"394bac4e.8eac34","name":"Reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":210,"y":1140,"wires":[["836123d6.09da6"]]},{"id":"a39721a5.1bdd9","type":"inject","z":"394bac4e.8eac34","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"go","payloadType":"str","x":790,"y":1280,"wires":[["da0a527b.cff23"]]},{"id":"9c0448ad.8b94c8","type":"server","z":"","name":"Home Assistant"}]

@zachowj
Copy link
Owner

zachowj commented Oct 11, 2020

Yes, my tests show the same thing.

I see that you're using the hass.io addon if you want to test these changes before the next release of the addon you can add the following to the node-red addon config and it will install the latest version of this package once it has been updated on npm.

npm_packages:
  - node-red-contrib-home-assistant-websocket@latest

@crkochan
Copy link
Author

The very definition of agile development.

Enjoy some coffee on me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants