Creating a timer that starts at a different time every day?

Hi! I’m trying to migrate some pistons from WebCoRE and one of the last ones I’m doing, and maybe the most important: my washing machine timer.

I have an old washer that I connected to wifi through some switches, I need to be able to turn it on in the mornings but not always at the same time. Also, I’d like to be able to control this by talking with Google Assistant.

In WebCoRE I ended up creating a virtual dimmer switch and every 5% between 60 and 100% would mean a different start time between 6 and 10am. So if the night before I set the virtual dimmer to 75%, the washer would start at 7:30am. (There was a piston that would set a time variable based on the % of the dimmer, and then another piston that would start each day at the time indicated in the variable).

First, now that I’m migrating to a completely different platform, I’d like to know if there is any way at all to ask google to set a time instead of using the virtual dimmer. I guess the answer is probably “you could with Alexa” :stuck_out_tongue:
I’m here mostly to get advice on how to set the nodes to do the time thing. I imagine a time boolean or a variable being set by the virtual dimmer and then another node that checks the variable each day and turns on the washer at that time. I only tried this once and failed because I don’t know how to start :frowning:

Thanks everyone!
Rodrigo

Create a date time helper in HA

Google side options

  • You could stick with the virtual light by creating a template light. Then listen for the brightness change and set the date time helper accordingly.
  • You could make a HA button in NR for each time you want to set and then do custom routines in the google home app “Set washer to start at 6:30” and the action would be the button. Then on the NR side, the button would set the date timer helper.

Use the time node to listen for the date time helper to kick off the flow for the washer.

1 Like

Use a template input datetime in HA?

{{ (today_at("06:00").timestamp() + range(0, 14400) | random) | timestamp_custom('%H:%M:%S', False) }}

Note that today_at uses UTC, so you might need to give 06:00 an offset depending on your time zone :wink:
(just check with developer tool / template what {{ today_at(“06:00”) }} returns:
2022-12-09 06:00:00 +01:00

2 Likes

Ok great, thank you @Kermit and @aceindy for your replies.

I created the light template and also the time helper (it only contains time, since this action is only configurable for the next day, so I don’t need the date).

I was thinking that instead of having fixed times (70%=7am, 75%=7:30am, etc), I could create a sequence that converts the whole range, whichever the number is, so if I set it at 92% it could set the time helper at 9:06am.

I don’t necessarily need this, but I think it could help me learn a bit more about NodeRED.

I think I could do this using a range node and calculating by minutes (420 minutes is 7am and 600 minutes is 10am), but I need to find an easy way of converting the time helper’s time into minutes. In the moment, it gives me HH:MM:SS format, how do I convert this format into minutes?
I tried the node-red-contrib-moment but I don’t understand how to make it output minutes.

Thanks,
Rodrigo

Maybe this can guide you/give some ideas?
It is for my outside lights, turns on at 100% at sunset,
in 30 minutes it reduces to 70%,
and at dawn, it goes from 70% up to 100% again😉

[{"id":"da384b51.789ff8","type":"counter","z":"722b415b.c3383","name":"Count from 100 to 70","init":"100","step":"1","lower":"70","upper":"","mode":"decrement","outputs":1,"x":740,"y":100,"wires":[["9bf9fab7.c5b4a8"]]}]

Thanks for your reply @aceindy, though I don’t understand how that could help me.

I needed a node that could convert between minutes to HH:MM:SS, but I ended up asking ChatGPT for a code :laughing:

This is it in case anyone wants it:

[{"id":"d003ae84ed49aa68","type":"function","z":"67e6ea55f99444c8","name":"convertMinutesToTime","func":"// Define a function to convert minutes to time\nfunction convertMinutesToTime(minutes) {\n    // Calculate the hours, minutes, and seconds\n    var hours = Math.floor(minutes / 60);\n    var remainingMinutes = Math.round(minutes % 60);\n    var seconds = 0;\n\n    // Pad the hours, minutes, and seconds with zeroes\n    // to ensure that they are two digits long\n    if (hours < 10) {\n        hours = \"0\" + hours;\n    }\n    if (remainingMinutes < 10) {\n        remainingMinutes = \"0\" + remainingMinutes;\n    }\n    if (seconds < 10) {\n        seconds = \"0\" + seconds;\n    }\n\n    // Concatenate the hours, minutes, and seconds into a time string\n    var time = hours + \":\" + remainingMinutes + \":\" + seconds;\n\n    return time;\n}\n\n// Use the function to convert the msg.data.new_state.attributes.brightness variable\nmsg.payload = convertMinutesToTime(msg.data.new_state.attributes.brightness);\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":860,"wires":[["614ffee7b8a71847"]]}]

R.

[{"id":"794e1df3b2fc1d13","type":"inject","z":"c89d915bdff0f798","name":"random percent","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"$floor(($random() * 100) + 1)","payloadType":"jsonata","x":192,"y":944,"wires":[["83e6e41f63cbfa25"]]},{"id":"83e6e41f63cbfa25","type":"range","z":"c89d915bdff0f798","minin":"1","maxin":"100","minout":"360","maxout":"600","action":"clamp","round":true,"property":"payload","name":"","x":356,"y":944,"wires":[["d310673ee939da0a"]]},{"id":"d310673ee939da0a","type":"function","z":"c89d915bdff0f798","name":"create timestamp","func":"const today = new Date();\ntoday.setHours(0);\ntoday.setSeconds(0);\ntoday.setMilliseconds(0);\ntoday.setMinutes(msg.payload);\n\nmsg.payload = today.getTime() / 1000;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":538,"y":944,"wires":[["2504d6ba4c4d7562"]]},{"id":"2504d6ba4c4d7562","type":"api-call-service","z":"c89d915bdff0f798","name":"","server":"","version":5,"debugenabled":false,"domain":"input_datetime","service":"set_datetime","areaId":[],"deviceId":[],"entityId":["input_datetime.test_2"],"data":"{\"timestamp\": payload}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":776,"y":944,"wires":[[]]},{"id":"e2c3413a4e9d3268","type":"inject","z":"c89d915bdff0f798","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":162,"y":976,"wires":[["83e6e41f63cbfa25"]]},{"id":"c80ead4464d4a380","type":"inject","z":"c89d915bdff0f798","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"100","payloadType":"num","x":162,"y":1104,"wires":[["83e6e41f63cbfa25"]]},{"id":"41d6abc5445b816f","type":"inject","z":"c89d915bdff0f798","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"5","payloadType":"num","x":162,"y":1008,"wires":[["83e6e41f63cbfa25"]]},{"id":"f6f7eb1c614202b3","type":"inject","z":"c89d915bdff0f798","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"92","payloadType":"num","x":162,"y":1072,"wires":[["83e6e41f63cbfa25"]]},{"id":"ec41502b89c00365","type":"inject","z":"c89d915bdff0f798","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"50","payloadType":"num","x":162,"y":1040,"wires":[["83e6e41f63cbfa25"]]}]
1 Like

Hi everyone again, so I created a beautiful sequence that converts percentage to time and even shows that time on my dashboard.

And I created these nodes to react every day at the time indicated in the input_datetime entity.

[{"id":"1bfe504b99b1cd0c","type":"ha-time","z":"67e6ea55f99444c8","name":"Next Wash Cycle Time","server":"8a86b0cc.b2bac","version":2,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityId":"input_datetime.next_wash_cycle_time","property":"state","offset":0,"offsetType":"num","offsetUnits":"minutes","randomOffset":false,"repeatDaily":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"sunday":true,"monday":true,"tuesday":true,"wednesday":true,"thursday":true,"friday":true,"saturday":true,"debugenabled":false,"x":140,"y":980,"wires":[["7d029880532d5751"]]},{"id":"7d029880532d5751","type":"api-current-state","z":"67e6ea55f99444c8","name":"IF Next Wash Cycle ON","server":"8a86b0cc.b2bac","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"light.next_wash_cycle","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":390,"y":980,"wires":[["a67dab55e1aff44f"],[]]},{"id":"a67dab55e1aff44f","type":"api-call-service","z":"67e6ea55f99444c8","name":"Wash Cycle ON","server":"8a86b0cc.b2bac","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_on","areaId":[],"deviceId":[],"entityId":["input_boolean.wm_wash_cycle"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":620,"y":980,"wires":[["6743a834138d3f8f"]]},{"id":"8a86b0cc.b2bac","type":"server","name":"Home Assistant R","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

But yesterday I tried it for the first time, the entity shows 5:10AM, but the flow didn’t trigger.

What can I do for this to start daily?

Thanks,
R.

FYI the datetime boolean only has time, not date. I don’t need to set a date since this action will only be set at night to be enabled in the next morning.

image

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/time.html#repeat-daily

1 Like

Thank you @Kermit !! Solved :smiley: