Timer stops early

I have some very simple timers setup for a sprinkler controller I built.

99% of the time it works just fine. The timers kick off from being started by a node red flow and are stopped by a node red flow if you click a button.

Once in a while a timer will end minutes before it is supposed to. I have monitored the logs and node red and nothing is kicking off in my flow to stop the timer.

Can you post a screenshot and maybe also the export json of your flow?

You will need the secret custom node as I use it to store some secret items for the api.
Basically the flow just triggers from an “on” or “off” to input.boolean and then checks if other switches are “on” in a group. Either way after this it calls the Rachio api to turn on a sprinkler zone.

99% percent of the time it works as expected. Then occasionally a timer will have been started and I will see it in the gui running. After about 1 minute has counted down the timer will just stop and revert to an idle state.

[{"id":"9d931426.bb1f98","type":"tab","label":"Rachio Run Zones","disabled":false,"info":""},{"id":"3d03ef0d.036a4","type":"secret","z":"9d931426.bb1f98","name":"Bearer Token","x":970,"y":60,"wires":[["af185ff3.e58fc"]]},{"id":"af185ff3.e58fc","type":"function","z":"9d931426.bb1f98","name":"Create Bearer Token","func":"msg.headers = {\n    Authorization: \"Bearer \"+ msg.secret\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1200,"y":60,"wires":[["62636235.2a91dc"]]},{"id":"a72d735f.78ec4","type":"www-request","z":"9d931426.bb1f98","name":"Get Person Info","method":"GET","ret":"obj","url":"","follow-redirects":false,"persistent-http":false,"tls":"","x":1600,"y":120,"wires":[["6265a118.12e74"]]},{"id":"9a512483.abcec8","type":"secret","z":"9d931426.bb1f98","name":"Person ID","x":960,"y":120,"wires":[["b4b186cb.1fd298"]]},{"id":"b4b186cb.1fd298","type":"change","z":"9d931426.bb1f98","name":"Create Person ID","rules":[{"t":"set","p":"personid","pt":"msg","to":"secret","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1190,"y":120,"wires":[["1c7a78b0.c673b7"]]},{"id":"1c7a78b0.c673b7","type":"template","z":"9d931426.bb1f98","name":"Set API Url","field":"url","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"https://api.rach.io/1/public/person/{{personid}}","output":"str","x":1410,"y":120,"wires":[["a72d735f.78ec4"]]},{"id":"6265a118.12e74","type":"change","z":"9d931426.bb1f98","name":"Get enabled zones from Rachio","rules":[{"t":"set","p":"zones","pt":"msg","to":"payload.devices.zones[enabled=true].{\"zoneNumber\": zoneNumber, \"id\": id}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1030,"y":220,"wires":[["fb48b425.b756e8"]]},{"id":"fb48b425.b756e8","type":"change","z":"9d931426.bb1f98","name":"Retrieve zone submitted","rules":[{"t":"set","p":"zone","pt":"msg","to":"(\t    $zone := $substring(topic,-1) ~> $number;\t    *[zoneNumber=$zone].id\t)\t\t","tot":"jsonata"},{"t":"set","p":"timer","pt":"msg","to":"(\t    $duration := $substring(topic,-1) ~> $number;\t    $duration := \"input_number.sprinkler_qrruntime_zone\" & $duration;\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1310,"y":220,"wires":[["3a714733.fe92b8"]]},{"id":"595cf50f.4da1ac","type":"www-request","z":"9d931426.bb1f98","name":"Call Rachio Zone Start API","method":"PUT","ret":"txt","url":"","follow-redirects":false,"persistent-http":false,"tls":"","x":1020,"y":280,"wires":[["2425213c.c98fbe"]]},{"id":"6335ad9f.a893d4","type":"change","z":"9d931426.bb1f98","name":"Set zone info","rules":[{"t":"set","p":"zonejson","pt":"msg","to":"{\t   \"id\": zone,\t   \"duration\": duration\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1710,"y":220,"wires":[["f9c709fc.3c9028"]]},{"id":"f9c709fc.3c9028","type":"function","z":"9d931426.bb1f98","name":"Set values for Rachio API","func":"msg.payload = msg.zonejson;\nmsg.headers = {\n    \"Authorization\": \"Bearer \"+ msg.bearer,\n    \"Content-Type\": \"application/json\"\n};\nmsg.url = 'https://api.rach.io/1/public/zone/start';\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1930,"y":220,"wires":[["b0cd81f4.50162"]]},{"id":"b0cd81f4.50162","type":"change","z":"9d931426.bb1f98","name":"Remove old msg","rules":[{"t":"delete","p":"zonejson","pt":"msg"},{"t":"delete","p":"zones","pt":"msg"},{"t":"delete","p":"personid","pt":"msg"},{"t":"delete","p":"topic","pt":"msg"},{"t":"delete","p":"bearer","pt":"msg"},{"t":"delete","p":"zone","pt":"msg"},{"t":"delete","p":"secret","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2170,"y":220,"wires":[["595cf50f.4da1ac"]]},{"id":"62636235.2a91dc","type":"change","z":"9d931426.bb1f98","name":"Create Person ID","rules":[{"t":"set","p":"bearer","pt":"msg","to":"secret","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1430,"y":60,"wires":[["9a512483.abcec8"]]},{"id":"3a714733.fe92b8","type":"function","z":"9d931426.bb1f98","name":"Round Duration","func":"const globalHomeAssistant = global.get('homeassistant');\nconst $timer = msg.timer;\nconst state = globalHomeAssistant.homeAssistant.states[$timer].state;\nconst removedDecimal = Math.round(state);\nmsg.duration = removedDecimal * 60;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1540,"y":220,"wires":[["6335ad9f.a893d4"]]},{"id":"55c1497f.b33b58","type":"api-call-service","z":"9d931426.bb1f98","name":"","server":"b9eb4c89.0f03f","version":1,"debugenabled":true,"service_domain":"timer","service":"start","entityId":"","data":"{\t   \"duration\": msg.duration,\t   \"entity_id\": msg.timer\t}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1680,"y":280,"wires":[["ccdf2a96.d9fdf8"]]},{"id":"2425213c.c98fbe","type":"switch","z":"9d931426.bb1f98","name":"","property":"statusCode","propertyType":"jsonata","rules":[{"t":"eq","v":"204","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1290,"y":280,"wires":[["41b86fc0.d41c3"]]},{"id":"476800e3.e68ca","type":"api-render-template","z":"9d931426.bb1f98","name":"Get on entity","server":"b9eb4c89.0f03f","template":"{% for entity_id in states.group.sprinkler_all_zones.attributes.entity_id -%}\n{% set domain, device = entity_id.split('.') -%}\n{% set entity = states[domain][device] %}\n{% if entity.state == \"on\" %}\n{{ entity.entity_id }}\n{% endif %}\n{% endfor %}","resultsLocation":"switch","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":410,"y":60,"wires":[["6b679731.8cd5c8"]]},{"id":"6b679731.8cd5c8","type":"switch","z":"9d931426.bb1f98","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":3,"x":170,"y":180,"wires":[["40988f69.8270f"],["f194687e.feae58"],[]]},{"id":"2eee57ae.966ee8","type":"api-call-service","z":"9d931426.bb1f98","name":"","server":"b9eb4c89.0f03f","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"","data":"{\t    \"entity_id\": msg.ib\t}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":560,"y":280,"wires":[["3d03ef0d.036a4"]]},{"id":"40988f69.8270f","type":"switch","z":"9d931426.bb1f98","name":"","property":"switch","propertyType":"msg","rules":[{"t":"neq","v":"","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":570,"y":140,"wires":[["cc8ea22f.d33fc"],["3d03ef0d.036a4"]]},{"id":"cc8ea22f.d33fc","type":"function","z":"9d931426.bb1f98","name":"","func":"myswitch = msg.switch;\nlastChar = myswitch.substring(myswitch.length - 1);\nmsg.ib = \"input_boolean.sprinkler_submit_zone\" + lastChar;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":560,"y":200,"wires":[["2eee57ae.966ee8"]]},{"id":"ccdf2a96.d9fdf8","type":"debug","z":"9d931426.bb1f98","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1810,"y":500,"wires":[]},{"id":"f194687e.feae58","type":"switch","z":"9d931426.bb1f98","name":"","property":"switch","propertyType":"msg","rules":[{"t":"else"},{"t":"neq","v":"","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":330,"y":200,"wires":[[],["c4367a78.0684b8"]]},{"id":"c4367a78.0684b8","type":"function","z":"9d931426.bb1f98","name":"","func":"myswitch = msg.switch;\nlastChar = myswitch.substring(myswitch.length - 1);\nmsg.char = lastChar;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":120,"y":260,"wires":[["11f694cc.463deb"]]},{"id":"11f694cc.463deb","type":"template","z":"9d931426.bb1f98","name":"","field":"items","fieldType":"msg","format":"json","syntax":"mustache","template":"{\n    \"ib\": \"input_boolean.sprinkler_submit_zone{{char}}\",\n    \"switch\": \"switch.sprinkler_zone{{char}}\",\n    \"timer\": \"timer.sprinkler_qr_zone{{char}}\"\n}","output":"json","x":280,"y":260,"wires":[["aac836e2.5e2e98","da4c669d.0a1ed8","cd8268c9.6a2e08"]]},{"id":"cc674132.dbcf8","type":"api-call-service","z":"9d931426.bb1f98","name":"","server":"b9eb4c89.0f03f","version":1,"debugenabled":true,"service_domain":"timer","service":"finish","entityId":"","data":"{\t    \"entity_id\": msg.items.timer\t}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":500,"y":480,"wires":[["ccdf2a96.d9fdf8"]]},{"id":"b2dafd5b.1dbae","type":"api-call-service","z":"9d931426.bb1f98","name":"","server":"b9eb4c89.0f03f","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"","data":"{\t    \"entity_id\": msg.items.switch\t}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":510,"y":360,"wires":[[]]},{"id":"3cda756d.b4bb0a","type":"api-call-service","z":"9d931426.bb1f98","name":"","server":"b9eb4c89.0f03f","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"","data":"{\t    \"entity_id\": msg.items.ib\t}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":540,"y":420,"wires":[[]]},{"id":"96f7c060.fc989","type":"api-current-state","z":"9d931426.bb1f98","name":"Check entity on","server":"b9eb4c89.0f03f","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"","state_type":"str","state_location":"","override_payload":"none","entity_location":"payload","override_data":"msg","blockInputOverrides":false,"x":280,"y":400,"wires":[["b2dafd5b.1dbae"],[]]},{"id":"64834a7b.9372a4","type":"api-current-state","z":"9d931426.bb1f98","name":"Check entity on","server":"b9eb4c89.0f03f","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"","state_type":"str","state_location":"","override_payload":"none","entity_location":"payload","override_data":"msg","blockInputOverrides":false,"x":280,"y":460,"wires":[["3cda756d.b4bb0a"],[]]},{"id":"feb108a2.b17838","type":"api-current-state","z":"9d931426.bb1f98","name":"Check entity on","server":"b9eb4c89.0f03f","version":1,"outputs":2,"halt_if":"active","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"","state_type":"str","state_location":"","override_payload":"none","entity_location":"payload","override_data":"msg","blockInputOverrides":false,"x":280,"y":520,"wires":[["cc674132.dbcf8"],[]]},{"id":"aac836e2.5e2e98","type":"function","z":"9d931426.bb1f98","name":"","func":"msg.payload = {\n  entity_id: msg.items.ib\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":100,"y":440,"wires":[["64834a7b.9372a4"]]},{"id":"da4c669d.0a1ed8","type":"function","z":"9d931426.bb1f98","name":"","func":"msg.payload = {\n  entity_id: msg.items.switch\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":100,"y":400,"wires":[["96f7c060.fc989"]]},{"id":"cd8268c9.6a2e08","type":"function","z":"9d931426.bb1f98","name":"","func":"msg.payload = {\n  entity_id: msg.items.timer\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":100,"y":480,"wires":[["feb108a2.b17838"]]},{"id":"41b86fc0.d41c3","type":"function","z":"9d931426.bb1f98","name":"","func":"ib = msg.data.entity_id;\nlastChar = ib.substring(ib.length - 1);\nmsg.timer = \"timer.sprinkler_qr_zone\" + lastChar;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1460,"y":280,"wires":[["55c1497f.b33b58"]]},{"id":"b7aefd9d.e0a74","type":"trigger-state","z":"9d931426.bb1f98","name":"Run when clicked","server":"b9eb4c89.0f03f","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"input_boolean.sprinkler_submit_zone","entityidfiltertype":"substring","debugenabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"current_state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"on","propertyValue":"new_state.state"}],"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":110,"y":40,"wires":[["476800e3.e68ca"],[]]},{"id":"6593845e.c1f0fc","type":"trigger-state","z":"9d931426.bb1f98","name":"Run when clicked","server":"b9eb4c89.0f03f","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"input_boolean.sprinkler_submit_zone","entityidfiltertype":"substring","debugenabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"current_state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off","propertyValue":"new_state.state"}],"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":110,"y":100,"wires":[["476800e3.e68ca"],[]]},{"id":"b9eb4c89.0f03f","type":"server","z":"","name":"Home Assistant","addon":true}]

Ah I see you are using the HA Timer. Have you tried using a timer from within NodeRed? i.e.: stoptimer, eztimer, etc. ?

I have not. I will try the eztimer and just write the time every minute or so back to the frontend.

This is what I am using for a dynamic timer:

[{"id":"762b3846.4a5a18","type":"server-state-changed","z":"f28a8271.df143","name":"Timer","version":1,"entityidfilter":"input_number.bedroom_fantime","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"0","halt_if_type":"num","halt_if_compare":"lte","outputs":2,"output_only_on_state_change":true,"x":90,"y":980,"wires":[[],["efed7a03.a97558"]]},{"id":"efed7a03.a97558","type":"function","z":"f28a8271.df143","name":"on/off?","func":"newmsg = {};\nif (msg.payload == \"1.0\")\n{\n    newmsg.payload = \"True\";\n}else {\n    newmsg.payload = \"STOP\";\n}\n\nreturn newmsg;","outputs":1,"noerr":0,"x":310,"y":980,"wires":[["29e2b309.8447dc"]]},{"id":"29e2b309.8447dc","type":"stoptimer","z":"f28a8271.df143","duration":"1","units":"Minute","payloadtype":"num","payloadval":"1","name":"","x":700,"y":980,"wires":[["3e6cc84d.89de78"],[]]},{"id":"f397f3e0.7e85d","type":"server-state-changed","z":"f28a8271.df143","name":"Fantime On?","version":1,"entityidfilter":"input_number.bedroom_fantime","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"0","halt_if_type":"num","halt_if_compare":"lte","outputs":2,"output_only_on_state_change":false,"x":370,"y":1100,"wires":[[],["9e15b410.66c768"]]},{"id":"6a7eb16e.13243","type":"api-call-service","z":"f28a8271.df143","name":"Fan Time","version":1,"debugenabled":false,"service_domain":"input_number","service":"set_value","entityId":"input_number.bedroom_fantime","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":900,"y":1060,"wires":[[]]},{"id":"145ddf1c.554511","type":"function","z":"f28a8271.df143","name":"Fantime - 1","func":"newmsg = {}\n\nnewmsg.payload = { data: { \"value\":(msg.payload - 1)} }\n\nreturn newmsg;\n","outputs":1,"noerr":0,"x":710,"y":1060,"wires":[["6a7eb16e.13243"]]},{"id":"d7308d63.2c81","type":"status","z":"f28a8271.df143","name":"","scope":["f397f3e0.7e85d"],"x":100,"y":1060,"wires":[["267f5c0b.2ec884"]]},{"id":"267f5c0b.2ec884","type":"switch","z":"f28a8271.df143","name":"","property":"status.text","propertyType":"msg","rules":[{"t":"eq","v":"connected","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":230,"y":1060,"wires":[["af3188bd.4d1168"]]},{"id":"af3188bd.4d1168","type":"api-current-state","z":"f28a8271.df143","name":"Fantime?","version":1,"outputs":2,"halt_if":"0","halt_if_type":"num","halt_if_compare":"lte","override_topic":false,"entity_id":"input_number.bedroom_fantime","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":360,"y":1060,"wires":[[],["9e15b410.66c768"]]},{"id":"9e15b410.66c768","type":"stoptimer","z":"f28a8271.df143","duration":"1","units":"Minute","payloadtype":"num","payloadval":"0","name":"1m","x":530,"y":1060,"wires":[["145ddf1c.554511"],[]]},{"id":"3e6cc84d.89de78","type":"api-call-service","z":"f28a8271.df143","name":"Schlafzimmer Off","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.schlafzimmer","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":930,"y":980,"wires":[[]]},{"id":"979f3486.2acd28","type":"comment","z":"f28a8271.df143","name":"Dyson Bedroom Timer","info":"","x":140,"y":940,"wires":[]}]

Basically an input_number that then will be updated every minute by node red (-1).