How to increase time after X minutes?

Hi!
In node-red, how do I extend a delay timer by X minutes, if a sensor is triggered?
Let me explain: I have a pir sensor that turns on a light, if another light is turned off and if current time is night time. If these triggers are true, the light is turned on for 5 minutes.
What I really want is that after initial timer start, if sensor is triggered again, add +2 minutes to the light timmer. My PIR sensor has a timeout of 1 minute, so I think adding +1 minute on each ‘detection’ will be fine…but how do I get this?

This is my current flow:

[
    {
        "id": "c60afa80.acc318",
        "type": "tab",
        "label": "Spot Noturno Copa",
        "disabled": false,
        "info": ""
    },
    {
        "id": "a8581414.fd9928",
        "type": "server-state-changed",
        "z": "c60afa80.acc318",
        "name": "Copa",
        "server": "2ba92c0c.9dae24",
        "version": 4,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "binary_sensor.sala_de_jantar_pir_occupancy",
        "entityidfiltertype": "exact",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 1,
        "output_only_on_state_change": true,
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": false,
        "ignorePrevStateUnknown": false,
        "ignorePrevStateUnavailable": false,
        "ignoreCurrentStateUnknown": false,
        "ignoreCurrentStateUnavailable": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            }
        ],
        "x": 130,
        "y": 280,
        "wires": [
            [
                "c44f5425.21fcf8",
                "b3e460bc.40055"
            ]
        ]
    },
    {
        "id": "c1778193.e6f73",
        "type": "time-range-switch",
        "z": "c60afa80.acc318",
        "name": "",
        "lat": "-20.5414",
        "lon": "-47.4025",
        "startTime": "21:00",
        "endTime": "07:00",
        "startOffset": 0,
        "endOffset": 0,
        "x": 570,
        "y": 200,
        "wires": [
            [
                "7426341644098565"
            ],
            []
        ]
    },
    {
        "id": "eba96d0.1bb539",
        "type": "delay",
        "z": "c60afa80.acc318",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "minutes",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "outputs": 1,
        "x": 1400,
        "y": 420,
        "wires": [
            [
                "40bad5b1.cccd0c"
            ]
        ]
    },
    {
        "id": "9686ccb3.00f14",
        "type": "api-call-service",
        "z": "c60afa80.acc318",
        "name": "Liga Spot Copa",
        "server": "2ba92c0c.9dae24",
        "version": 5,
        "debugenabled": false,
        "domain": "light",
        "service": "turn_on",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "light.sala_de_jantar_spot_4"
        ],
        "data": "{\"brightness_pct\": 20, \"color_temp\": 370}",
        "dataType": "json",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1420,
        "y": 300,
        "wires": [
            [
                "eba96d0.1bb539"
            ]
        ]
    },
    {
        "id": "40bad5b1.cccd0c",
        "type": "api-call-service",
        "z": "c60afa80.acc318",
        "name": "Desliga Spot Copa",
        "server": "2ba92c0c.9dae24",
        "version": 5,
        "debugenabled": false,
        "domain": "light",
        "service": "turn_off",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "light.sala_de_jantar_spot_4"
        ],
        "data": "",
        "dataType": "json",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1630,
        "y": 540,
        "wires": [
            []
        ]
    },
    {
        "id": "c44f5425.21fcf8",
        "type": "switch",
        "z": "c60afa80.acc318",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "on",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 360,
        "y": 280,
        "wires": [
            [
                "c1778193.e6f73"
            ]
        ]
    },
    {
        "id": "5b1fb03.82bfb5",
        "type": "inject",
        "z": "c60afa80.acc318",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 1200,
        "y": 100,
        "wires": [
            [
                "9686ccb3.00f14"
            ]
        ]
    },
    {
        "id": "ebac1854.ba02f8",
        "type": "inject",
        "z": "c60afa80.acc318",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 1340,
        "y": 600,
        "wires": [
            [
                "40bad5b1.cccd0c"
            ]
        ]
    },
    {
        "id": "b3e460bc.40055",
        "type": "debug",
        "z": "c60afa80.acc318",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 390,
        "y": 560,
        "wires": []
    },
    {
        "id": "7426341644098565",
        "type": "api-current-state",
        "z": "c60afa80.acc318",
        "name": "",
        "server": "2ba92c0c.9dae24",
        "version": 3,
        "outputs": 2,
        "halt_if": "off",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "light.sala_de_jantar_spot_1",
        "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",
        "x": 920,
        "y": 240,
        "wires": [
            [
                "cdbd8749a13089f1"
            ],
            []
        ]
    },
    {
        "id": "cdbd8749a13089f1",
        "type": "api-current-state",
        "z": "c60afa80.acc318",
        "name": "",
        "server": "2ba92c0c.9dae24",
        "version": 3,
        "outputs": 2,
        "halt_if": "off",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "light.sala_de_jantar_spot_2",
        "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",
        "x": 920,
        "y": 300,
        "wires": [
            [
                "d159f89173b2d36e"
            ],
            []
        ]
    },
    {
        "id": "d159f89173b2d36e",
        "type": "api-current-state",
        "z": "c60afa80.acc318",
        "name": "",
        "server": "2ba92c0c.9dae24",
        "version": 3,
        "outputs": 2,
        "halt_if": "off",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "light.sala_de_jantar_spot_3",
        "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",
        "x": 920,
        "y": 360,
        "wires": [
            [
                "86dea2d728940e94"
            ],
            []
        ]
    },
    {
        "id": "86dea2d728940e94",
        "type": "api-current-state",
        "z": "c60afa80.acc318",
        "name": "Luz Sala desligada",
        "server": "2ba92c0c.9dae24",
        "version": 3,
        "outputs": 2,
        "halt_if": "off",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "light.interruptor_sala",
        "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",
        "x": 990,
        "y": 420,
        "wires": [
            [
                "4e6d019ea6ac4dd2"
            ],
            []
        ]
    },
    {
        "id": "4e6d019ea6ac4dd2",
        "type": "api-current-state",
        "z": "c60afa80.acc318",
        "name": "Luz Cozinha desligada",
        "server": "2ba92c0c.9dae24",
        "version": 3,
        "outputs": 2,
        "halt_if": "off",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "light.luz_cozinha",
        "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",
        "x": 980,
        "y": 480,
        "wires": [
            [
                "9686ccb3.00f14"
            ],
            []
        ]
    },
    {
        "id": "2ba92c0c.9dae24",
        "type": "server",
        "name": "Home Assistant",
        "version": 2,
        "addon": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": 30
    }
]

instead of a delay node you could use varidelay. You’ll have control over the remaining time of the timer thus allowing you to add the desired amount of extra time.

there might be a better way, but I believe this will behave as you expect

[{"id":"c80f74b6.9ee688","type":"trigger-state","z":"c60afa80.acc318","name":"triggers","server":"9405c3fe.d0a6c","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"binary_sensor.sala_de_jantar_pir_occupancy","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"targetType":"entity_id","targetValue":"light.sala_de_jantar_spot_1","propertyType":"current_state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off","propertyValue":"new_state.state"},{"targetType":"entity_id","targetValue":"light.sala_de_jantar_spot_2","propertyType":"current_state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off","propertyValue":"new_state.state"},{"targetType":"entity_id","targetValue":"light.sala_de_jantar_spot_3","propertyType":"current_state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off","propertyValue":"new_state.state"},{"targetType":"entity_id","targetValue":"light.interruptor_sala","propertyType":"current_state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off","propertyValue":"new_state.state"},{"targetType":"entity_id","targetValue":"light.luz_cozinha","propertyType":"current_state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off","propertyValue":"new_state.state"},{"targetType":"this_entity","targetValue":"","propertyType":"current_state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"on","propertyValue":"new_state.state"}],"inputs":0,"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","enableInput":false,"x":190,"y":800,"wires":[["d26bf184.fac2c"],[]]},{"id":"d26bf184.fac2c","type":"time-range-switch","z":"c60afa80.acc318","name":"","lat":"-20.5414","lon":"-47.4025","startTime":"21:00","endTime":"07:00","startOffset":0,"endOffset":0,"x":330,"y":800,"wires":[["a2f55d4c.e6829"],[]]},{"id":"a2f55d4c.e6829","type":"api-call-service","z":"c60afa80.acc318","name":"Liga Spot Copa","server":"2ba92c0c.9dae24","version":5,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":["light.sala_de_jantar_spot_4"],"data":"{\"brightness_pct\": 20, \"color_temp\": 370}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":500,"y":800,"wires":[["d0bb29b9.0f8c08"]]},{"id":"4f422984.e1c2a8","type":"stoptimer-varidelay","z":"c60afa80.acc318","duration":"5","durationType":"num","units":"Second","payloadtype":"num","payloadval":"0","name":"","reporting":"every_second","persist":true,"x":1020,"y":800,"wires":[["457a2cd0.7b2814"],[],["85c357ef.d43968"]]},{"id":"85c357ef.d43968","type":"ha-entity","z":"c60afa80.acc318","name":"light flow remaining seconds","server":"9405c3fe.d0a6c","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"light_flow_remaining_seconds"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"$round($number($substring(payload,3,2)))*60 + $round($number($substring(payload,6,2)))","stateType":"jsonata","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1260,"y":860,"wires":[[]]},{"id":"457a2cd0.7b2814","type":"api-call-service","z":"c60afa80.acc318","name":"Desliga Spot Copa","server":"2ba92c0c.9dae24","version":5,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":["light.sala_de_jantar_spot_4"],"data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1230,"y":760,"wires":[[]]},{"id":"d0bb29b9.0f8c08","type":"api-current-state","z":"c60afa80.acc318","name":"remainig time?","server":"9405c3fe.d0a6c","version":3,"outputs":2,"halt_if":"1","halt_if_type":"num","halt_if_compare":"gte","entity_id":"sensor.light_flow_remaining_seconds","state_type":"num","blockInputOverrides":true,"outputProperties":[{"property":"time","propertyType":"msg","value":"","valueType":"entityState"}],"for":0,"forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":680,"y":800,"wires":[["bd84c1c3.d4e83"],["c9ba3be5.c30848"]]},{"id":"bd84c1c3.d4e83","type":"change","z":"c60afa80.acc318","name":"set delay","rules":[{"t":"set","p":"delay","pt":"msg","to":"$number(time) + 120","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":850,"y":780,"wires":[["4f422984.e1c2a8"]]},{"id":"c9ba3be5.c30848","type":"change","z":"c60afa80.acc318","name":"set delay","rules":[{"t":"set","p":"delay","pt":"msg","to":"300","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":850,"y":820,"wires":[["4f422984.e1c2a8"]]},{"id":"9405c3fe.d0a6c","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30},{"id":"2ba92c0c.9dae24","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]

I think the easiest way is to just use the merge node.
Each time this node gets a new message it will reset the timer and only send a message further on when the timeout set for the node has been reached without new message arriving to the node.

that’s definetely the easiest

Merge node? Do you mean join node?

No, it is called merge.
Maybe I have installed node-red-contrib-merge manually, but I do not recall so.

billede

billede

It seems to just collect all the message arriving and then first send it when the timeout from the last received message arrive.
If you need to work with the messages arriving, then you might need to do some handling.
The first one would always be msg,payload[0], but the last one would be msg.payload[n], where n is the number of arrived messages before timeout.
A little javascript would quickly solve that issue.

1 Like

You can achieve the same with the stock trigger node, checking the “Extend Delay If New Message Arrives” and “Send Second Message To Separate Output

[{"id":"29eeb24a.15fc9e","type":"inject","z":"937ef78.ec6b408","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":210,"y":220,"wires":[["8e18656b.f8edd8"]]},{"id":"8e18656b.f8edd8","type":"trigger","z":"937ef78.ec6b408","name":"","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"5","extend":true,"overrideDelay":false,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":2,"x":360,"y":220,"wires":[["83ab9bbb.d912a8"],["da436cfc.d4fc5"]]},{"id":"83ab9bbb.d912a8","type":"api-call-service","z":"937ef78.ec6b408","name":"turn on","server":"9405c3fe.d0a6c","version":3,"debugenabled":false,"service_domain":"","service":"","entityId":"","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":520,"y":200,"wires":[["5323d591.91404c"]]},{"id":"da436cfc.d4fc5","type":"api-call-service","z":"937ef78.ec6b408","name":"turn off","server":"9405c3fe.d0a6c","version":3,"debugenabled":false,"service_domain":"","service":"","entityId":"","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":530,"y":240,"wires":[["59bd88c0.998b78"]]},{"id":"5323d591.91404c","type":"debug","z":"937ef78.ec6b408","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":650,"y":200,"wires":[]},{"id":"59bd88c0.998b78","type":"debug","z":"937ef78.ec6b408","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":650,"y":240,"wires":[]},{"id":"9405c3fe.d0a6c","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]