# Node-red-contrib-cron-plus and Save State

**URL:** <https://discourse.nodered.org/t/node-red-contrib-cron-plus-and-save-state/96855>\
**Category:** General\
**Tags:** cron-plus\
**Created:** [2 May 2025 13:43 UTC](https://discourse.nodered.org/t/node-red-contrib-cron-plus-and-save-state/96855 "2025-05-02T13:43:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jnn](https://avatars.discourse-cdn.com/v4/letter/j/b3f665/32.png) [@jnn](https://discourse.nodered.org/u/jnn)\
**Post date:** [2 May 2025 13:43 UTC](https://discourse.nodered.org/t/node-red-contrib-cron-plus-and-save-state/96855/1 "2025-05-02T13:43:44Z")

</div>

Hi,  
I’m using the node-red-contrib-cron-plus node (version 2.1.0 with Node-RED 4.0.9) to start a flow every day at 16:00.  
I also have another cron-plus node that stops the flow at 21:00 each evening.

However, if the computer is shut down for example, due to an unexpected power outage after 16:00 and then restarted, the flow doesn’t run until 16:00 the next day.  
That means the event is essentially lost if the system was offline at the scheduled time.

I’ve enabled the Save State option and selected File: local file system, but how should I configure it? Is there an example flow available?

Is there a recommended way to detect or recover from missed schedule events?  
Or is there a better alternative for ensuring the flow starts if it was missed during downtime?

Any advice, example flows, or best practices would be very much appreciated.  
Thanks!

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [2 May 2025 15:04 UTC](https://discourse.nodered.org/t/node-red-contrib-cron-plus-and-save-state/96855/2 "2025-05-02T15:04:11Z")

</div>

> [@jnn](#):
>
> start a flow every day at 16:00.

What do you mean by this? Do you have a msg looping forever until it is stopped at 21:00?

There are things you can do at startup like an inject set to trigger after 0.1s - you can use that to determined if the time is valid to "start your flow"

---

<div class="post-metadata">

**Author:** ![juntiedt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/juntiedt/32/58357_2.png) [@juntiedt](https://discourse.nodered.org/u/juntiedt)\
**Post date:** [2 May 2025 15:06 UTC](https://discourse.nodered.org/t/node-red-contrib-cron-plus-and-save-state/96855/3 "2025-05-02T15:06:44Z")

</div>

You don't need 2 cron plus nodes to get your result.

I would recommend, that you are sending your commands every 5 min and put a filter between cronplus and your device. Then it would start latest 5 min after reboot to send the commands.  
check cron guidelines for periods.

I am using this method for my heating system and it works perfectly.

---

<div class="post-metadata">

**Author:** ![jnn](https://avatars.discourse-cdn.com/v4/letter/j/b3f665/32.png) [@jnn](https://discourse.nodered.org/u/jnn)\
**Post date:** [2 May 2025 15:20 UTC](https://discourse.nodered.org/t/node-red-contrib-cron-plus-and-save-state/96855/4 "2025-05-02T15:20:18Z")

</div>

Thanks for your quick replies. Sorry if I was unclear. Maybe it’s easier if I show you a copy of my flow.

```auto
[
    {
        "id": "261f4e79e74055a7",
        "type": "tab",
        "label": "Test",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "de88c3da99ce4e3f",
        "type": "serial request",
        "z": "261f4e79e74055a7",
        "name": "",
        "serial": "ccaf0526df580fed",
        "x": 950,
        "y": 300,
        "wires": [
            [
                "a6e8f7f960057c36"
            ]
        ]
    },
    {
        "id": "c9f41354ae47aaaa",
        "type": "function",
        "z": "261f4e79e74055a7",
        "name": "Add <CR>",
        "func": "msg.payload += \"\\r\";\nreturn msg; ",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 690,
        "y": 300,
        "wires": [
            [
                "de88c3da99ce4e3f"
            ]
        ]
    },
    {
        "id": "f048436be7eef71b",
        "type": "comment",
        "z": "261f4e79e74055a7",
        "name": "Read RGB values every second between 16:00 and 21:00",
        "info": "",
        "x": 270,
        "y": 260,
        "wires": []
    },
    {
        "id": "108f253b3df8cc74",
        "type": "comment",
        "z": "261f4e79e74055a7",
        "name": "-- STOP --",
        "info": "",
        "x": 120,
        "y": 400,
        "wires": []
    },
    {
        "id": "a4afcc3cbdc3d75d",
        "type": "http request",
        "z": "261f4e79e74055a7",
        "name": "OLA Set DMX",
        "method": "POST",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://localhost:9090/set_dmx",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 760,
        "y": 480,
        "wires": [
            []
        ]
    },
    {
        "id": "a0550cc720fb0a52",
        "type": "function",
        "z": "261f4e79e74055a7",
        "name": "Blackout",
        "func": "var dmxValues = \"0,0,0\";\nmsg.payload = {\n u: 1,\n d: dmxValues\n};\nmsg.headers = {\n 'Content-Type': 'application/x-www-form-urlencoded'\n};\n\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 600,
        "y": 480,
        "wires": [
            [
                "a4afcc3cbdc3d75d"
            ]
        ]
    },
    {
        "id": "812f46f53fe20e17",
        "type": "delay",
        "z": "261f4e79e74055a7",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 460,
        "y": 480,
        "wires": [
            [
                "a0550cc720fb0a52"
            ]
        ]
    },
    {
        "id": "08b1aba77d5e9c3b",
        "type": "function",
        "z": "261f4e79e74055a7",
        "name": "Read RGB value",
        "func": "var outputMsg = { payload: 'r' };\nreturn outputMsg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 510,
        "y": 300,
        "wires": [
            [
                "c9f41354ae47aaaa"
            ]
        ]
    },
    {
        "id": "9202fd7b14eb71ac",
        "type": "cronplus",
        "z": "261f4e79e74055a7",
        "name": "Set LED brightness to 0 % at 21:01",
        "outputField": "payload",
        "timeZone": "",
        "storeName": "file",
        "commandResponseMsgOutput": "output1",
        "defaultLocation": "",
        "defaultLocationType": "default",
        "outputs": 1,
        "options": [
            {
                "name": "time",
                "topic": "time",
                "payloadType": "date",
                "payload": "",
                "expressionType": "cron",
                "expression": "01 21 * * *",
                "location": "",
                "offset": "0",
                "solarType": "all",
                "solarEvents": "sunrise,sunset"
            }
        ],
        "x": 220,
        "y": 440,
        "wires": [
            [
                "812f46f53fe20e17",
                "807a9066f3cd8c1e",
                "e5477089ee32ee0b"
            ]
        ]
    },
    {
        "id": "807a9066f3cd8c1e",
        "type": "delay",
        "z": "261f4e79e74055a7",
        "name": "",
        "pauseType": "delay",
        "timeout": "15",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 460,
        "y": 520,
        "wires": [
            [
                "6a77d1bed4dd3e83"
            ]
        ]
    },
    {
        "id": "6a77d1bed4dd3e83",
        "type": "http request",
        "z": "261f4e79e74055a7",
        "name": "Shutdown OLA",
        "method": "GET",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://localhost:9090/quit",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 620,
        "y": 520,
        "wires": [
            []
        ]
    },
    {
        "id": "b4f5289545d7e708",
        "type": "exec",
        "z": "261f4e79e74055a7",
        "command": "olad -f",
        "addpay": false,
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 370,
        "y": 100,
        "wires": [
            [],
            [],
            []
        ]
    },
    {
        "id": "5f4d38ff0e23e31f",
        "type": "cronplus",
        "z": "261f4e79e74055a7",
        "name": "Every second between 16:00 and 21:00",
        "outputField": "payload",
        "timeZone": "",
        "storeName": "",
        "commandResponseMsgOutput": "output1",
        "defaultLocation": "",
        "defaultLocationType": "default",
        "outputs": 1,
        "options": [
            {
                "name": "evening_trigger",
                "topic": "evening_trigger",
                "payloadType": "date",
                "payload": "",
                "expressionType": "cron",
                "expression": "*/1 * 16-20 * * *",
                "location": "",
                "offset": "0",
                "solarType": "all",
                "solarEvents": "sunrise,sunset"
            }
        ],
        "x": 240,
        "y": 300,
        "wires": [
            [
                "08b1aba77d5e9c3b"
            ]
        ]
    },
    {
        "id": "5376f56dcefed806",
        "type": "comment",
        "z": "261f4e79e74055a7",
        "name": "-- START --",
        "info": "#",
        "x": 130,
        "y": 60,
        "wires": []
    },
    {
        "id": "e5477089ee32ee0b",
        "type": "function",
        "z": "261f4e79e74055a7",
        "name": "Set LED brightness to 0 %",
        "func": "var outputMsg = { payload: 'L,0' };\nreturn outputMsg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 520,
        "y": 440,
        "wires": [
            [
                "a3613f3f26cff17a"
            ]
        ]
    },
    {
        "id": "12ef3850e35f6f60",
        "type": "cronplus",
        "z": "261f4e79e74055a7",
        "name": "Start OLA at 15:59",
        "outputField": "payload",
        "timeZone": "",
        "storeName": "file",
        "commandResponseMsgOutput": "output1",
        "defaultLocation": "",
        "defaultLocationType": "default",
        "outputs": 1,
        "options": [
            {
                "name": "time",
                "topic": "time",
                "payloadType": "date",
                "payload": "",
                "expressionType": "cron",
                "expression": "59 15 * * *",
                "location": "",
                "offset": "0",
                "solarType": "all",
                "solarEvents": "sunrise,sunset"
            }
        ],
        "x": 170,
        "y": 100,
        "wires": [
            [
                "b4f5289545d7e708"
            ]
        ]
    },
    {
        "id": "378f4b62bf59ca39",
        "type": "function",
        "z": "261f4e79e74055a7",
        "name": "Set LED brightness to 90 %",
        "func": "var outputMsg = { payload: 'L,90' };\nreturn outputMsg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 520,
        "y": 160,
        "wires": [
            [
                "86f70d3c9b34b51e"
            ]
        ]
    },
    {
        "id": "70475b19b0357ca3",
        "type": "cronplus",
        "z": "261f4e79e74055a7",
        "name": "Set LED brightness to 90 % at 16:00",
        "outputField": "payload",
        "timeZone": "",
        "storeName": "file",
        "commandResponseMsgOutput": "output1",
        "defaultLocation": "",
        "defaultLocationType": "default",
        "outputs": 1,
        "options": [
            {
                "name": "time",
                "topic": "time",
                "payloadType": "date",
                "payload": "",
                "expressionType": "cron",
                "expression": "00 16 * * *",
                "location": "",
                "offset": "0",
                "solarType": "all",
                "solarEvents": "sunrise,sunset"
            }
        ],
        "x": 230,
        "y": 160,
        "wires": [
            [
                "378f4b62bf59ca39"
            ]
        ]
    },
    {
        "id": "a3613f3f26cff17a",
        "type": "function",
        "z": "261f4e79e74055a7",
        "name": "Add <CR>",
        "func": "msg.payload += \"\\r\";\nreturn msg; ",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 730,
        "y": 440,
        "wires": [
            [
                "de88c3da99ce4e3f"
            ]
        ]
    },
    {
        "id": "86f70d3c9b34b51e",
        "type": "function",
        "z": "261f4e79e74055a7",
        "name": "Add <CR>",
        "func": "msg.payload += \"\\r\";\nreturn msg; ",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 730,
        "y": 160,
        "wires": [
            [
                "de88c3da99ce4e3f"
            ]
        ]
    },
    {
        "id": "b0079f04f5550aed",
        "type": "http request",
        "z": "261f4e79e74055a7",
        "name": "OLA Set DMX",
        "method": "POST",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://localhost:9090/set_dmx",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 1440,
        "y": 300,
        "wires": [
            []
        ]
    },
    {
        "id": "6644018ab414267d",
        "type": "comment",
        "z": "261f4e79e74055a7",
        "name": "-- Send DMX values to OLA --",
        "info": "",
        "x": 1440,
        "y": 260,
        "wires": []
    },
    {
        "id": "a6e8f7f960057c36",
        "type": "function",
        "z": "261f4e79e74055a7",
        "name": "Send RGB values (scale to 0-255)",
        "func": "var message = msg.payload;\n\nif (message && typeof message === 'string') {\n var values = message.split(',');\n\n if (values.length >= 3) {\n var red = values[0];\n var green = values[1];\n var blue = values[2].replace(\"*OK\", \"\").trim();\n\n var redValue = parseInt(red);\n var greenValue = parseInt(green);\n var blueValue = parseInt(blue);\n\n redValue = Math.min(redValue, 255);\n greenValue = Math.min(greenValue, 255);\n blueValue = Math.min(blueValue, 255);\n\n var universe = 1; \n msg.headers = {'Content-Type': 'application/x-www-form-urlencoded'};\n msg.payload = \"u=\" + universe + \"&d=\" + redValue + \",\" + greenValue + \",\" + blueValue;\n }\n}\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1200,
        "y": 300,
        "wires": [
            [
                "b0079f04f5550aed"
            ]
        ]
    },
    {
        "id": "ccaf0526df580fed",
        "type": "serial-port",
        "name": "EZO RGB Sensor",
        "serialport": "/dev/ttyUSB0",
        "serialbaud": "9600",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "waitfor": "",
        "dtr": "none",
        "rts": "none",
        "cts": "none",
        "dsr": "none",
        "newline": "\\n",
        "bin": "false",
        "out": "char",
        "addchar": "",
        "responsetimeout": "1"
    }
]

```

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [2 May 2025 18:28 UTC](https://discourse.nodered.org/t/node-red-contrib-cron-plus-and-save-state/96855/5 "2025-05-02T18:28:25Z")

</div>

For simple on off then the [node-red-node-timeswitch](https://flows.nodered.org/node/node-red-node-timeswitch) can do a simple on off once a day - and will send the value 0 or 1 either only on the transitions, or once per minute - which can then be followed by a filter (RBE) node so that it only sends once if restarted.

---

<div class="post-metadata">

**Author:** ![jnn](https://avatars.discourse-cdn.com/v4/letter/j/b3f665/32.png) [@jnn](https://discourse.nodered.org/u/jnn)\
**Post date:** [3 May 2025 08:51 UTC](https://discourse.nodered.org/t/node-red-contrib-cron-plus-and-save-state/96855/6 "2025-05-03T08:51:44Z")

</div>

Thanks! I will try Timeswitch and RBE filter.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [17 May 2025 08:52 UTC](https://discourse.nodered.org/t/node-red-contrib-cron-plus-and-save-state/96855/7 "2025-05-17T08:52:01Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
