How to use Input_Number in node-red

I have messed around with Node-Red a couple of times, but could never figure out how to migrate some of my existing automations to Node-Red and still have the same functionality that I have using Yaml automations. I have several light automations that allow me to dynamically change the sunrise/sunset offset times from the HA front end without needing to go in and edit any code or change any permanent settings. For Example, I have the following control panel for my Porch Light that will allow me to dynamically change the sunset/sunrise offset using a slider which in turn specifies the time when I actually want to porch lights to come on.

image

I have a sensor setup the takes the input_number offset values from the input number sliders and uses that set the time I want the lights to turn on/off.

platform: template
sensors:
  porch_light_am_off_after_sunrise:
    friendly_name: 'Light Off Time '
    value_template: '{{ (as_timestamp(states.sun.sun.attributes.next_rising) + (states("input_number.porch_light_am_off_after_sunrise") | int)  * 60)  | timestamp_custom("%I:%M %p", True) }}'

I then have a simple automation that turns the lights on/off at the time in the sensor.

alias: porch_light_am_off_after_sunrise
initial_state: true
trigger:
  - platform: time_pattern
    minutes: '/1'
    seconds: 00
condition:
  condition: and
  conditions:
  - condition: template
    value_template: '{{ as_timestamp (now()) | timestamp_custom("%I:%M %p", True) == states.sensor.porch_light_am_off_after_sunrise.state }}'
  - condition: state
    entity_id: switch.front_porch_light
    state: 'on'
action:
  - service: switch.turn_off
    entity_id: switch.front_porch_light

I know in Node-Red I can use Bigtimer to manually specify an offset, but I want it to be dynamic so that I can continue to use the sliders in my HA frontend to control the offset. How can I do this in Node-Red? Can I use the input_number as an input to bigtimer, or as I already have a sensor that calculates when I want the lights on/off can I use those sensors directly to trigger node-red to call the switch.turn_off/on service? If I use the sensor with the time value, i.e. ā€˜07:30 AMā€™, what is the node in Node-Red I use to trigger the automation at this time?

I really appreciate the help. I want to start migrating more of my automations over to Node-Red, but not being able to figure out how to get this to work has been the sticking point.

Andrew J

1 Like

You can use any message and set it as the data payload in a service call via a function node.

Best way to start with any new node is to create a new flow with:

events state: (In your case the Input_Number) and connect this to a debug node (Set it to capture the complete output, not just the payload)

Then play around with your input_number and check in your debug log the change in value. From here you can copy the path of the message. In this case the actual value is in the payload: msg.payload

You can then use this msg in a function node and manipulate the value or send it as the data payload to a service call.

I use this for Alexa TTS for example:

> [{"id":"8122993.f85e268","type":"function","z":"508a1885.e71948","name":"Message","func":"newmsg = {}\n\nnewmsg.payload = { data: { \"message\":msg.message} }\n\nreturn newmsg;\n","outputs":1,"noerr":0,"x":840,"y":180,"wires":[["cd9b540a.29b668"]]},{"id":"cd9b540a.29b668","type":"api-call-service","z":"508a1885.e71948","name":"Notify Voice","server":"2fba4297.e4145e","version":"1","service_domain":"notify","service":"alexa_media_wohnung","entityId":"","data":"{\"title\":\"Home Assistant\",\"data\":{\"type\":\"announce\",\"method\":\"all\"}}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":990,"y":180,"wires":[[]]},{"id":"cd423960.cf0c68","type":"switch","z":"508a1885.e71948","name":"Message","property":"message","propertyType":"msg","rules":[{"t":"nempty"}],"checkall":"true","repair":false,"outputs":1,"x":700,"y":180,"wires":[["8122993.f85e268"]]},{"id":"2fba4297.e4145e","type":"server","z":"","name":"Home Assistant","legacy":false,"hassio":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true}]

I wanted to do the something similar but a bit different.
I use an input boolean for allowing my daughter to read at night and have her lights stay on for longer before they automatically turn off.

image
I have built something pretty ugly in my view but it works so thatā€™s a bonus.

Iā€™m using a mytimeout node (the pink one) for a countdown timer which allows injecting the timer from the msg.payload. I use a function node to massage the msg.payload to the right format to inject the input_number (in seconds) into a mytimeout node which counts down the time before turning the input_boolean off, checking the light is on and turning it off (I check itā€™ on first to save extra z-wave messages).

The transform function just does the following:

t=msg.payload * 60
newMSG = { "warning": 0, "timeout": t}
return newMSG;

Like I said, pretty ugly but it works. If anyone has anything more elegant, Iā€™m happy to be shown a better wayā€¦

This is the full flow for the kidā€™s bedrooms:

2 Likes

Hi Alan,

Can you please make an export of your Node-RED flow, so that I can see how this is working. Thanks in advance.

Sorry for the delay in response.

Here is the export of the flow around the reading timer. Actually, itā€™s the whole flow for the room as itā€™s all linked. Iā€™ve also separated out each room to its own flow so it should be cleaner.

The ā€œZoe is readingā€ switch is exposed to Alexa. When you turn on the switch (via Alexa or HA), it kicks off the revised flow which sets a timer in node-red based on the input_number in HA. I havenā€™t gotten around to exposing the input_number to Alexa directly yet (so we could potentially ask Alexa to extend it etc).

I added to the reading timer so now Alexa also tells me what the timer is set to when it is turned on or changed. Both in Zoeā€™s room, so she knows, and on the main Echo Show upstairs.

Let me know if that was helpful or you have any other questions.

[{"id":"7eefbb29.7f6c44","type":"server-state-changed","z":"7731bf7a.40e1e","name":"Zoe is reading","server":"488c48af.01013","version":1,"entityidfilter":"input_boolean.zoe_is_reading","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":92,"y":483,"wires":[["d022ca14.ba1428","b2d278f7.6a2b98"],[]]},{"id":"ec45fbb8.8fadc8","type":"server-state-changed","z":"7731bf7a.40e1e","name":"Motion in Zoe's Room","server":"488c48af.01013","version":1,"entityidfilter":"binary_sensor.zoes_room_sensor_137","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":183,"y":278,"wires":[["80d0f9c3.44f5d8"],[]]},{"id":"71b615a7.56860c","type":"stoptimer","z":"7731bf7a.40e1e","duration":"30","units":"Minute","payloadtype":"num","payloadval":"msg.payload","name":"","x":815,"y":167,"wires":[["e02f3218.15954"],[]]},{"id":"221dfb80.ba9904","type":"api-call-service","z":"7731bf7a.40e1e","name":"Turn off Zoe's light","server":"488c48af.01013","version":"1","service_domain":"light","service":"turn_off","entityId":"light.zoes_light_37","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1754,"y":205,"wires":[[]]},{"id":"21833ce5.307484","type":"api-current-state","z":"7731bf7a.40e1e","name":"Is light on?","server":"488c48af.01013","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":true,"entity_id":"light.zoes_light_37","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":1545,"y":200,"wires":[["221dfb80.ba9904"],[]]},{"id":"40311688.1f7098","type":"server-state-changed","z":"7731bf7a.40e1e","name":"Zoe's Light switched on","server":"488c48af.01013","version":1,"entityidfilter":"light.zoes_light_37","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":175,"y":158,"wires":[["a1457040.f7d6a","80d0f9c3.44f5d8","c03fbcf9.e6086"],[]]},{"id":"80d0f9c3.44f5d8","type":"time-range-switch","z":"7731bf7a.40e1e","name":"Between 6am and 8.30pm","lat":"","lon":"","startTime":"06:00","endTime":"20:30","startOffset":0,"endOffset":0,"x":549,"y":190,"wires":[["71b615a7.56860c"],["a2cea6c4.bb84f8"]]},{"id":"a2cea6c4.bb84f8","type":"stoptimer","z":"7731bf7a.40e1e","duration":"5","units":"Minute","payloadtype":"num","payloadval":"msg.payload","name":"","x":821,"y":212,"wires":[["e02f3218.15954"],[]]},{"id":"23c71804.8ee528","type":"api-call-service","z":"7731bf7a.40e1e","name":"Brightness to 5%","server":"488c48af.01013","version":1,"service_domain":"light","service":"turn_on","entityId":"light.zoes_light_37","data":"{\"brightness_pct\":5}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1567,"y":123,"wires":[[]]},{"id":"a1457040.f7d6a","type":"time-range-switch","z":"7731bf7a.40e1e","name":"","lat":"","lon":"","startTime":"07:00","endTime":"20:30","startOffset":"","endOffset":0,"x":870,"y":88,"wires":[["4a90d590.db689c"],["5da34ba.81d61b4"]]},{"id":"4a90d590.db689c","type":"api-call-service","z":"7731bf7a.40e1e","name":"Brightness to 100%","server":"488c48af.01013","version":"1","service_domain":"light","service":"turn_on","entityId":"light.zoes_light_37","data":"{\"brightness_pct\":100}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1568,"y":66,"wires":[[]]},{"id":"e02f3218.15954","type":"api-current-state","z":"7731bf7a.40e1e","name":"Is Zoe reading?","server":"488c48af.01013","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.zoe_is_reading","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":1068,"y":189,"wires":[[],["21833ce5.307484"]]},{"id":"b936f227.594a9","type":"api-call-service","z":"7731bf7a.40e1e","name":"Turn off Zoe is reading flag","server":"488c48af.01013","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.zoe_is_reading","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1280,"y":381,"wires":[["21833ce5.307484"]]},{"id":"5da34ba.81d61b4","type":"api-current-state","z":"7731bf7a.40e1e","name":"Is Zoe reading?","server":"488c48af.01013","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.zoe_is_reading","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":1192,"y":113,"wires":[["d022ca14.ba1428"],["23c71804.8ee528"]]},{"id":"c03fbcf9.e6086","type":"time-range-switch","z":"7731bf7a.40e1e","name":"Between 12am and 8.30pm","lat":"","lon":"","startTime":"00:00","endTime":"20:30","startOffset":0,"endOffset":0,"x":541,"y":272,"wires":[[],["f1bdf7af.fa9fb8"]]},{"id":"d918191.db449e8","type":"time-range-switch","z":"7731bf7a.40e1e","name":"Between 12am and 8.30pm","lat":"","lon":"","startTime":"00:00","endTime":"20:30","startOffset":0,"endOffset":0,"x":780,"y":319,"wires":[[],["a2ecf0fa.25f9e"]]},{"id":"2bda4bcd.bc4694","type":"api-call-service","z":"7731bf7a.40e1e","name":"Alexa Speak - Echo Show","server":"488c48af.01013","version":1,"debugenabled":false,"service_domain":"notify","service":"alexa_media_alan_s_echo_show","entityId":"","data":"{\"message\":\"{{payload}}\",\"data\":{\"type\":\"announce\",\"method\":\"speak\"}}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1314,"y":247,"wires":[[]]},{"id":"f1bdf7af.fa9fb8","type":"change","z":"7731bf7a.40e1e","name":"Zoe's light is on","rules":[{"t":"set","p":"payload","pt":"msg","to":"Zoe's light is on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":843,"y":273,"wires":[["2bda4bcd.bc4694"]]},{"id":"d022ca14.ba1428","type":"api-call-service","z":"7731bf7a.40e1e","name":"Brightness to 70%","server":"488c48af.01013","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.zoes_light_37","data":"{\"brightness_pct\":70}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1676,"y":439,"wires":[[]]},{"id":"eddb1198.9a9ea","type":"function","z":"7731bf7a.40e1e","name":"Transform to seconds","func":"t=msg.payload * 60\nnewMSG = { \"warning\": 0, \"timeout\": t}\nreturn newMSG;","outputs":1,"noerr":0,"x":778.5,"y":390,"wires":[["2343523e.51eb8e"]]},{"id":"2343523e.51eb8e","type":"mytimeout","z":"7731bf7a.40e1e","name":"Countdown","outtopic":"","outsafe":"","outwarning":"Warning","outunsafe":"off","warning":"0","timer":"30","debug":false,"ndebug":false,"ignoreCase":false,"repeat":false,"again":false,"x":1017.5,"y":392,"wires":[["b936f227.594a9","d8f9ae2d.f7709"],[]]},{"id":"6d675d48.918be4","type":"api-current-state","z":"7731bf7a.40e1e","name":"Check Zoe's Timer","server":"488c48af.01013","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_number.zoe_reading_timer","state_type":"num","state_location":"payload","override_payload":"msg","entity_location":"entity_id","override_data":"msg","blockInputOverrides":false,"x":494,"y":336,"wires":[["d918191.db449e8","eddb1198.9a9ea"]]},{"id":"b36fb1fa.e3c36","type":"server-state-changed","z":"7731bf7a.40e1e","name":"Zoe Reading Timer changed","server":"488c48af.01013","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.zoe_reading_timer","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"x":147,"y":344,"wires":[["6d675d48.918be4"]]},{"id":"a2ecf0fa.25f9e","type":"function","z":"7731bf7a.40e1e","name":"Reading timer msg","func":"t=msg.payload\nt2=\"The Zoe is reading timer is set for \" \nt3=\" minutes\"    \nnewMSG = { \"payload\": t2 + t + t3}\nreturn newMSG","outputs":1,"noerr":0,"x":1037,"y":321,"wires":[["2bda4bcd.bc4694","18d524d8.487f2b"]]},{"id":"d1894780.429388","type":"api-call-service","z":"7731bf7a.40e1e","name":"Alexa Speak - Zoe's Echo","server":"488c48af.01013","version":1,"debugenabled":false,"service_domain":"notify","service":"alexa_media_zoe_s_room_echo_dot","entityId":"","data":"{\"message\":\"{{payload}}\",\"data\":{\"type\":\"announce\"}}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1465,"y":320,"wires":[[]]},{"id":"18d524d8.487f2b","type":"delay","z":"7731bf7a.40e1e","name":"","pauseType":"delay","timeout":"6","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1253,"y":322,"wires":[["d1894780.429388"]]},{"id":"b2d278f7.6a2b98","type":"api-call-service","z":"7731bf7a.40e1e","name":"Turn on Zoe is reading flag","server":"488c48af.01013","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.zoe_is_reading","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":270,"y":406,"wires":[["6d675d48.918be4"]]},{"id":"db4590e2.a9ee4","type":"server-state-changed","z":"7731bf7a.40e1e","name":"Zoe is reading is switched off","server":"488c48af.01013","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.zoe_is_reading","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":199,"y":552,"wires":[["ace2b205.0aac8"],[]]},{"id":"75fcb239.60e0ec","type":"api-call-service","z":"7731bf7a.40e1e","name":"Turn off Zoe's light","server":"488c48af.01013","version":"1","service_domain":"light","service":"turn_off","entityId":"light.zoes_light_37","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":734,"y":547,"wires":[[]]},{"id":"ace2b205.0aac8","type":"api-current-state","z":"7731bf7a.40e1e","name":"Is light on?","server":"488c48af.01013","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":true,"entity_id":"light.zoes_light_37","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":486,"y":545,"wires":[["75fcb239.60e0ec"],[]]},{"id":"86e5d862.077f08","type":"change","z":"7731bf7a.40e1e","name":"Reading timer finished","rules":[{"t":"set","p":"payload","pt":"msg","to":"Zoe's reading timer has finished","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1071,"y":592,"wires":[["2bda4bcd.bc4694"]]},{"id":"d8f9ae2d.f7709","type":"api-current-state","z":"7731bf7a.40e1e","name":"Is light on?","server":"488c48af.01013","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":true,"entity_id":"light.zoes_light_37","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":1032,"y":510,"wires":[["86e5d862.077f08"],[]]},{"id":"1f62bd71.07a973","type":"inject","z":"7731bf7a.40e1e","name":"","topic":"","payload":"on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":748,"y":711,"wires":[["a2ecf0fa.25f9e"]]},{"id":"488c48af.01013","type":"server","z":"","name":"Home Assistant","legacy":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true}]

Hi Alan,

I think i can use this for something i want to build. I want to set a timer in HA with a slider like you do, and start that timer with a switch in HA.

I have a few questions.

  1. How do you have made the slider to set a timer or the input_number in HA?
  2. Do you think when de flow is running in node-red i can set the countdown to pause with a pause button in HA?

I want to make a timer for my son, for how long he can play on the playstation.

Interesting. What is used to determine if a kid is reading?

Someone saying ā€œAlexa, turn on [xx kid] is Readingā€, switching it on manually in HA or changing the input_number associated with the reading timer.

All of those start the reading timer. There is no automatic way of knowing they are reading - although, that would be an awesome thing to work out with AI. Might have that conversation with my team at work.

  1. Will post the other information on how I built it tomorrow after work.
  2. Iā€™m sure you could do that somehow. If the timer node you use has a pause countdown, then yes.

I found this post which talks about a method for pausing the timer:

Iā€™m using mytimeout for this flow so that should work happily.

Will have a look and see if I can make it work in the next day or so.

Ok so looking at this configuration, I have a few questions:

  1. If you have a way to detect motion in the room, why not use that for setting the brightness level of the lights? Currently you seem to watch for the light being turned on and then adjust the brightness level based on time, wouldnā€™t it be preferable to leave the light switch as a manual override and instead based the lights on motion + sun level?
  2. If youā€™re just trying to turn the light off you donā€™t really have to check if its on first. Thereā€™s no harm to calling the turn_off service on an already off light.
  3. This confuses me a bit:
    Screen Shot 2020-06-15 at 9.12.31 AM
    Seems like you call a service to turn on input_boolean.zoe_is_reading after it has changed to on? Seems redundantā€¦
  4. One of the things I learned that helped me simplify my flows is you can refer to HA data anywhere you can use JSONata using this: $globalContext("homeassistant.homeAssistant.states['<insert entity ID here>'].state"). So you can use that to mix HA data into expressions in change/switch nodes without doing things like a get entity node followed by a change/function node. Also you can get to a lot more then just state this way, you can get to any of the attributes, last_changed/triggered, etc. You can see the global data you can access if you go to Context Data on the right side panel then dig into globals under homeassistant. You can see all HA state is just represented as a big JSON object there for you to use.
    Screen Shot 2020-06-15 at 9.19.39 AM
  5. Have you tried out the trigger: state node as opposed to the events: state? I notice a few places you have an events: state node followed by another conditional which only lets the message past if both conditions are met. Thatā€™s actually what the trigger: state node does. It watches for state changes in an entity but only allows the message to be past if a series of conditions defined by you evaluate to true. You can use details of the triggered entities past or current state in those conditions as well as as the current state of any other entities you wish.
1 Like

Answers. :slight_smile:

  1. The room is a childā€™s bedroom. I adjust the brightness based on time so itā€™s not 100% after a certain time - 100% on those lights is quite bright and when theyā€™re supposed to be asleep, a bright light isnā€™t a great idea. I considered using the motion sensor for switching the light on but it is not accurate enough plus the kids turn the lights on with Alexa which triggers the rest of the flow.
  2. I check the light is on before turning it off as the check is done in home_assistant while the lights are zwave devices through Vera and this stops unnecessary zwave messaging.
  3. That was actually a mistake. Turning on the flag was supposed to be connected to the timer being changed. I fixed thatā€¦
    image
  4. Hadnā€™t thought about that - was just trying to do it as easily as possible without a whole lot of coding. Will have a look at that when I have some time though.
  5. Mostly I did it that way as I was new to this node-red thing. I built these flows over several weeks while I was working out what was possible and what I wanted to actually happen. Then went back and added more stuff as my wife said ā€œcan we do this?ā€ or I thought ā€œthatā€™s annoying, I wonder if I can doā€¦ā€. I havenā€™t gone back over it to see if there are more efficient ways of doing the same thing. The way it is at the moment also makes it very easy to follow a flow and see what is/will happen. But I probably should re-visit this at some point.

That all makes sense. Other then those your flows all made sense to me. They can get definitely get visually complicated pretty quickly. Some tricks Iā€™ve found to help keep the complication down:

  1. Link nodes can be used to avoid crossing lines. Or if you have a very common event driving a lot of flows it can be easier to do it once and link from it. It still requires some mental hoops to keep track of but Iā€™ve found the line crossing to be the thing tends to make them visually complicated quickly. Usually Iā€™d rather have link nodes with labels but thatā€™s personal preference.
  2. You can create reusable subflows, they definitely help since it allows you to share pieces of the flow between them. You can also edit them in their own tab that you can close and hide away when youā€™re not editing (as well as giving them descriptions, labels, and inputs). Itā€™s a bit hidden away, you can make them up in the top right menu:
  3. Hopefully you figured this out already but the debug and inject nodes are definitely your best friends. Itā€™s so iterate and debug with those. Just attach a debug node, get the message and then use it in the jsonata tester or inject it in your flow at that spot. Also note that most of the HA nodes have a debug checkbox that pushes the message they receive into the debug window, very helpful as well.

So, the components in HA:

  1. An input_boolean for the reading flag (input_boolean.zoe_is_reading)
  2. An input_number for the timer (input_number.zoe_reading_timer)
zoe_reading_timer:
  name: Zoe Reading Timer
  icon: mdi:local_library
  min: 15
  max: 120
  step: 15
  unit_of_measurement: mins

The input_boolean:

zoe_is_reading:
    name: Zoe is reading

When the input_boolean is switched on (mostly by someone telling Alexa to turn it on), node-red pulls the value of the input_number from HA, changes that to seconds and then sends that value to the countdown node.

What I found through playing last night should make it easy to do what you want. Hereā€™s a modified flow to enable you to store and use the remaining time:

During normal operation, the countdown timer outputs the remaining time every second to the lower output.
If you inject an off message to the countdown timer, it resets/clears and outputs -1 to the lower output.
If you inject a stop message to the timer, it resets the timer but outputs the final countdown number to the lower output.

If you capture the output of the timer and export that to a flow variable, you can then use that to restart the timer from where you stopped it.

The first function node (that checks the variable and formats the message)

var remain = flow.get("ZoeTimeRemain");
var timer = msg.payload * 60;

    if  (remain > 0){
    msg.payload = {"timeout": remain, "warning": 30}; 
    return [msg];
    }
    
    else {
    msg.payload = {"timeout": timer, "warning": 30}; 
    return [msg];
    }

The filter after the countdown stops the -1 which is output on a stop command from being passed to the flow variable which ensures your flow variable keeps the remaining time (unless you turn it off by passing off to it).

The last function node just sets the flow variable based on the output from the countdown timer (which as mentioned, outputs the remaining time every second as it counts down)

flow.set("ZoeTimeRemain",msg.payload);

You may want to add some debug to that so you can see whatā€™s going on while youā€™re testing. In that case, use the following (or something like this):

flow.set("ZoeTimeRemain",msg.payload);
msg.payload = (msg.payload);
return msg;

Then you just need to have a button in HA for pause, probably linked to another input_boolean, that node-red uses as a trigger to send the stop command and on command again to restart where you left off.

This is now my revised flow that does everything it did before with the addition of pausing and continuing the timer.

The Pause Timer node:

  • outputs to the upper output if the input_boolean is switched on (pause)
  • outputs to the lower output if the input_boolean is switched off (resume)

The input_boolean:

zoe_timer_pause:
    name: Pause Zoe's Timer

There is also a filter node to remove the stop output when pausing the timer.

And the node red flows for all of this:

[{"id":"96cd19c4.6d4568","type":"api-current-state","z":"4d46f34d.a5668c","name":"Check Zoe's Timer","server":"488c48af.01013","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_number.zoe_reading_timer","state_type":"num","state_location":"payload","override_payload":"msg","entity_location":"entity_id","override_data":"msg","blockInputOverrides":false,"x":513.888916015625,"y":332.22216796875,"wires":[["b414f57e.eb7e78"]]},{"id":"7553264b.228478","type":"mytimeout","z":"4d46f34d.a5668c","name":"Countdown","outtopic":"","outsafe":"","outwarning":"Warning","outunsafe":"off","warning":"0","timer":"30","debug":false,"ndebug":false,"ignoreCase":false,"repeat":false,"again":false,"x":988.388916015625,"y":278.22216796875,"wires":[["96499f78.2ea3b"],["7e081f3b.ae9aa"]]},{"id":"7e081f3b.ae9aa","type":"switch","z":"4d46f34d.a5668c","name":"Filter >= 0","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"0","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":1171.888916015625,"y":346.22216796875,"wires":[["9dc050b0.1bff4"]]},{"id":"b414f57e.eb7e78","type":"function","z":"4d46f34d.a5668c","name":"check remaining time, if >0, set timer to that and format message","func":"var remain = flow.get(\"ZoeTimeRemain\");\nvar timer = msg.payload * 60;\n\n    if  (remain > 0){\n    msg.payload = {\"timeout\": remain, \"warning\": 30}; \n    return [msg];\n    }\n    \n    else {\n    msg.payload = {\"timeout\": timer, \"warning\": 30}; \n    return [msg];\n    }\n","outputs":1,"noerr":0,"x":626,"y":209,"wires":[["7553264b.228478"]]},{"id":"9dc050b0.1bff4","type":"function","z":"4d46f34d.a5668c","name":"Set flow variable ZoeTimeRemain (output for debug only)","func":"flow.set(\"ZoeTimeRemain\",msg.payload);\nmsg.payload = (msg.payload);\nreturn msg;","outputs":1,"noerr":0,"x":1300,"y":427,"wires":[["3d73ae43.a35e02"]]},{"id":"16c6ea7f.0defd6","type":"server-state-changed","z":"4d46f34d.a5668c","name":"Pause Timer?","server":"488c48af.01013","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.zoe_timer_pause","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":225,"y":452,"wires":[["389f3367.faf92c"],["96cd19c4.6d4568"]]},{"id":"389f3367.faf92c","type":"function","z":"4d46f34d.a5668c","name":"set msg.payload to \"stop\"","func":"msg.payload=(\"stop\")\nreturn msg","outputs":1,"noerr":0,"x":750,"y":380,"wires":[["7553264b.228478"]]},{"id":"d61bb1f0.aee3e","type":"server-state-changed","z":"4d46f34d.a5668c","name":"Zoe is reading","server":"488c48af.01013","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.zoe_is_reading","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":204,"y":246,"wires":[["96cd19c4.6d4568"],["7553264b.228478","4c6474c4.2b1c6c"]]},{"id":"f55f8837.c19c18","type":"api-call-service","z":"4d46f34d.a5668c","name":"Turn off Zoe is reading flag","server":"488c48af.01013","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.zoe_is_reading","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1357,"y":277,"wires":[["8c698d5e.cee07"]]},{"id":"8c698d5e.cee07","type":"api-current-state","z":"4d46f34d.a5668c","name":"Is light on?","server":"488c48af.01013","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":true,"entity_id":"light.zoes_light_37","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":1622,"y":232,"wires":[["11aae4d2.280f1b"],[]]},{"id":"11aae4d2.280f1b","type":"api-call-service","z":"4d46f34d.a5668c","name":"Turn off Zoe's light","server":"488c48af.01013","version":"1","service_domain":"light","service":"turn_off","entityId":"light.zoes_light_37","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1680,"y":342,"wires":[[]]},{"id":"3d73ae43.a35e02","type":"ha-entity","z":"4d46f34d.a5668c","name":"Zoe Timer Remaining","server":"488c48af.01013","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"nodered_test_name"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":"s"}],"state":"ZoeTimeRemain","stateType":"flow","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","x":1668,"y":428,"wires":[[]]},{"id":"96499f78.2ea3b","type":"switch","z":"4d46f34d.a5668c","name":"Stop anything that's not \"off\"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1241,"y":201,"wires":[["f55f8837.c19c18"]]},{"id":"4eefe5f3.998e6c","type":"server-state-changed","z":"4d46f34d.a5668c","name":"Zoe Reading Timer changed","server":"488c48af.01013","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.zoe_reading_timer","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"x":161,"y":305,"wires":[["633047b3.a683d8"]]},{"id":"633047b3.a683d8","type":"api-call-service","z":"4d46f34d.a5668c","name":"Turn on Zoe is reading flag","server":"488c48af.01013","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.zoe_is_reading","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":177.66665649414062,"y":379.77777099609375,"wires":[["96cd19c4.6d4568"]]},{"id":"4c6474c4.2b1c6c","type":"api-call-service","z":"4d46f34d.a5668c","name":"Turn off Zoe Timer Pause","server":"488c48af.01013","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.zoe_timer_pause","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":605,"y":450,"wires":[[]]},{"id":"488c48af.01013","type":"server","z":"","name":"Home Assistant","legacy":false,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

Iā€™m also exposing the flow variable to HA for a sensor but as that changes name every restart itā€™s a bit annoying. No idea how to template that so the sensor survives a reboot.

image

And Iā€™ve added a node to turn off the pause if the timer is switched off.

2 Likes

@CentralCommand Ha! Totally forgot about that debug option in the HA nodes. Iā€™ve just been adding debug nodes every time and then deleting them. Thatā€™ll make life easier!! :slight_smile:

Will look into the subflows and links too. What I have is basically static at the moment unless someone asks a question that requires tweaking to answer (like @Denman2103 or my wife mostly).

Thanks for the tips - Iā€™m all about making it easy to read - my wife keeps telling me this whole thing is toast if I die as she has no clue how it all hangs together!!

1 Like