Function node and ui_template (checkbox) does not exchange data

Hi,

I try to work with 24 checkboxes, but their statuses are never saved.
In my function node I want to find out, when 1 of the 24 checkbox status is changed. So I want to save the status in an array of 24 entries permanently in the flow. but it does not work. I am completely new on node red but I can program vb.net.

Which steps do I need to follow principally?

Thanks in advance.

BR Alois

I suggest first of all you should tell us if you are using dashboard 2 (@flowfuse/node-red-dashboard) or the original (node-red-dashboard)
Then share a flow so we can understand the problem. Maybe just 3 checkboxes would be sufficient to convey the issue.

Perhaps you mean flow context. Have you looked at https://nodered.org/docs/user-guide/context?

I am NOT using Dashboard 2, just the old one. How can I post a flow here in this forum? I got the message that new users cannot upload.

You can select the nodes of interest, export (compact option) and paste the exported JSON into a code block.


In order to make code readable and usable it is necessary to surround your code with three backticks (also known as a left quote or backquote ```)

``` 
   code goes here 
```

See this post for more details - How to share code or flow json

[
    {
        "id": "c66e7e564331dc31",
        "type": "function",
        "z": "38565ad851da076a",
        "name": "",
        "func": "var FL_Strompreise24 = flow.get(\"FL_Strompreise24\") || [];\nvar FL_Stunden24 = flow.get(\"FL_Stunden24\") || [];\nvar FL_CheckboxState = flow.get(\"FL_CheckboxState\") || new Array(24).fill(false);\n\nnode.warn(\"Empfangene msg.payload: \" + JSON.stringify(msg.payload));\n\n\nif (msg.payload && msg.payload.data && Array.isArray(msg.payload.data)) {\n    node.warn(\"Neue Daten empfangen, aktualisiere Strompreise...\");\n\n    FL_Strompreise24 = [];\n    FL_Stunden24 = [];\n\n    msg.payload.data.forEach((entry) => {\n        FL_Strompreise24.push(entry.marketprice / 10);\n        let date = new Date(entry.start_timestamp);\n        FL_Stunden24.push(date.getHours() + \":\" + (\"0\" + date.getMinutes()).slice(-2));\n    });\n\n    flow.set(\"FL_Strompreise24\", FL_Strompreise24);\n    flow.set(\"FL_Stunden24\", FL_Stunden24);\n\n    FL_CheckboxState = new Array(24).fill(false);\n    let indexedPrices = FL_Strompreise24.map((price, index) => ({ price, index }));\n    indexedPrices.sort((a, b) => a.price - b.price);\n\n    let lowestIndices = indexedPrices.slice(0, 4).map(entry => entry.index);\n    lowestIndices.forEach((index) => {\n        FL_CheckboxState[index] = true;\n    });\n\n    flow.set(\"FL_CheckboxState\", FL_CheckboxState);\n}\n\nif (msg.payload && msg.payload !== \"\") {\n    //node.warn(\"Trigger: Jede Sekunde, prüfe aktuelle Checkbox...\");\n \n    if (FL_Strompreise24.length > 0 && FL_Stunden24.length > 0) {\n        let now = new Date();\n        let currentHour = now.getHours();\n        let AkkuLaden = FL_CheckboxState[currentHour] ? 1 :0;\n\n        //node.warn(\"Checkboxen: \" + FL_CheckboxState);\n        //node.warn(\"Akkuladen: \" + AkkuLaden);\n        //node.warn(\"akt.Stunde: \" + currentHour);\n\n        let textOutput = {\n            payload: AkkuLaden ? \"Akku lädt\" : \"Akku wird nicht geladen\"\n        };\n\n        let chartOutput = {\n            payload: [{\n                series: [\"Strompreise\"],\n                data: [FL_Strompreise24],\n                labels: FL_Stunden24\n            }]\n        };\n\n        let checkboxOutput = {\n            payload: {\n                FL_Strompreise24: FL_Strompreise24,\n                FL_Stunden24: FL_Stunden24,\n                checkboxes: FL_CheckboxState\n            }\n        };\n\n        flow.set(\"FL_CheckboxState\", FL_CheckboxState);\n        flow.set(\"AkkuLaden\", AkkuLaden);\n\n        node.send([chartOutput, checkboxOutput, textOutput]);\n        //return [chartOutput, checkboxOutput, textOutput];\n    } else {\n        node.warn(\"Fehler: Keine gültigen Strompreise oder Stunden verfügbar!\");\n        return [null, null, null];\n    }\n} else {\n    node.warn(\"Fehler: Kein gültiger Trigger empfangen\");\n    return null;\n}\n",
        "outputs": 3,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 680,
        "y": 340,
        "wires": [
            [
                "97c93b6a5a4f021c"
            ],
            [
                "af86bf98ca546101"
            ],
            [
                "f179424e292e9072"
            ]
        ]
    }
]

this is my function node

and this my ui_template for the checkboxes

[
    {
        "id": "af86bf98ca546101",
        "type": "ui_template",
        "z": "38565ad851da076a",
        "group": "472a29f10598521a",
        "name": "Checkboxes Akku",
        "order": 6,
        "width": "12",
        "height": "1",
        "format": "<div style=\"display: flex; flex-wrap: wrap; gap: 3px;padding-left: 35px;\">\n  <div ng-repeat=\"n in [].constructor(24) track by $index\">\n    <label>\n      <input type=\"checkbox\" ng-model=\"checkboxes[$index]\" ng-change=\"sendCheckboxState()\">\n    </label>\n  </div>\n</div>\n\n<script>\n  (function(scope) {\n    // Initialisieren der Checkboxen, falls msg.payload.checkboxes verfügbar ist\n    scope.$watch('msg.payload', function(data) {\n      if (data && data.checkboxes) {\n        scope.checkboxes = data.checkboxes;  // Setze den Zustand der Checkboxen\n      } else {\n        scope.checkboxes = new Array(24).fill(false);  // Standard: Alle auf false setzen\n      }\n    });\n\n    // Funktion, um den Zustand der Checkboxen zu senden\n    scope.sendCheckboxState = function() {\n      // Prüfen, ob der Zustand der Checkboxen wirklich geändert wurde\n      var checkboxState = scope.checkboxes;  \n      \n      // Debug-Ausgabe: Ausgabe der geänderten Checkboxen im Debug-Fenster\n      scope.send({ payload: { checkboxes: scope.checkboxes, debug: \"Checkbox Zustand geändert\" } });\n      \n      // Sende die geänderten Checkboxen als msg an den Flow\n      scope.send({ payload: { checkboxes: checkboxState } });\n    };\n  })(scope);\n</script>\n",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 890,
        "y": 360,
        "wires": [
            [
                "e171cefbae2babe1"
            ]
        ]
    },
    {
        "id": "472a29f10598521a",
        "type": "ui_group",
        "name": "Awattar_Group",
        "tab": "2dde8bcb178d77da",
        "order": 2,
        "disp": true,
        "width": "15",
        "collapse": false,
        "className": ""
    },
    {
        "id": "2dde8bcb178d77da",
        "type": "ui_tab",
        "name": "Home",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]

Sorry, this did not work

[
    {
        "id": "c66e7e564331dc31",
        "type": "function",
        "z": "38565ad851da076a",
        "name": "",
        "func": "var FL_Strompreise24 = flow.get(\"FL_Strompreise24\") || [];\nvar FL_Stunden24 = flow.get(\"FL_Stunden24\") || [];\nvar FL_CheckboxState = flow.get(\"FL_CheckboxState\") || new Array(24).fill(false);\n\nnode.warn(\"Empfangene msg.payload: \" + JSON.stringify(msg.payload));\n\n\nif (msg.payload && msg.payload.data && Array.isArray(msg.payload.data)) {\n    node.warn(\"Neue Daten empfangen, aktualisiere Strompreise...\");\n\n    FL_Strompreise24 = [];\n    FL_Stunden24 = [];\n\n    msg.payload.data.forEach((entry) => {\n        FL_Strompreise24.push(entry.marketprice / 10);\n        let date = new Date(entry.start_timestamp);\n        FL_Stunden24.push(date.getHours() + \":\" + (\"0\" + date.getMinutes()).slice(-2));\n    });\n\n    flow.set(\"FL_Strompreise24\", FL_Strompreise24);\n    flow.set(\"FL_Stunden24\", FL_Stunden24);\n\n    FL_CheckboxState = new Array(24).fill(false);\n    let indexedPrices = FL_Strompreise24.map((price, index) => ({ price, index }));\n    indexedPrices.sort((a, b) => a.price - b.price);\n\n    let lowestIndices = indexedPrices.slice(0, 4).map(entry => entry.index);\n    lowestIndices.forEach((index) => {\n        FL_CheckboxState[index] = true;\n    });\n\n    flow.set(\"FL_CheckboxState\", FL_CheckboxState);\n}\n\nif (msg.payload && msg.payload !== \"\") {\n    //node.warn(\"Trigger: Jede Sekunde, prüfe aktuelle Checkbox...\");\n \n    if (FL_Strompreise24.length > 0 && FL_Stunden24.length > 0) {\n        let now = new Date();\n        let currentHour = now.getHours();\n        let AkkuLaden = FL_CheckboxState[currentHour] ? 1 :0;\n\n        //node.warn(\"Checkboxen: \" + FL_CheckboxState);\n        //node.warn(\"Akkuladen: \" + AkkuLaden);\n        //node.warn(\"akt.Stunde: \" + currentHour);\n\n        let textOutput = {\n            payload: AkkuLaden ? \"Akku lädt\" : \"Akku wird nicht geladen\"\n        };\n\n        let chartOutput = {\n            payload: [{\n                series: [\"Strompreise\"],\n                data: [FL_Strompreise24],\n                labels: FL_Stunden24\n            }]\n        };\n\n        let checkboxOutput = {\n            payload: {\n                FL_Strompreise24: FL_Strompreise24,\n                FL_Stunden24: FL_Stunden24,\n                checkboxes: FL_CheckboxState\n            }\n        };\n\n        flow.set(\"FL_CheckboxState\", FL_CheckboxState);\n        flow.set(\"AkkuLaden\", AkkuLaden);\n\n        node.send([chartOutput, checkboxOutput, textOutput]);\n        //return [chartOutput, checkboxOutput, textOutput];\n    } else {\n        node.warn(\"Fehler: Keine gültigen Strompreise oder Stunden verfügbar!\");\n        return [null, null, null];\n    }\n} else {\n    node.warn(\"Fehler: Kein gültiger Trigger empfangen\");\n    return null;\n}\n",
        "outputs": 3,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 680,
        "y": 340,
        "wires": [
            [
                "97c93b6a5a4f021c"
            ],
            [
                "af86bf98ca546101"
            ],
            [
                "f179424e292e9072"
            ]
        ]
    }
]

Sorry I donot know how to do. If I try to post a code (preview leftsided), on the reith side it looks completely different as you can see twice

You should supply the input data that youe function node creates, as this would be required to test.

From what i see you need to add a ng-value to your inputs. You can then save the data to flow context and recover when required.

[{"id":"f4c4d77d799e7852","type":"inject","z":"d1395164b4eec73e","name":"initialise","props":[{"p":"payload.checkboxes","v":"[true,false,true]","vt":"json"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":420,"y":5680,"wires":[["af86bf98ca546101"]]},{"id":"af86bf98ca546101","type":"ui_template","z":"d1395164b4eec73e","group":"472a29f10598521a","name":"Checkboxes Akku","order":6,"width":"12","height":"1","format":"<div style=\"display: flex; flex-wrap: wrap; gap: 3px;padding-left: 35px;\">\n  <div ng-repeat=\"n in msg.payload.checkboxes track by $index\">\n    <label>\n      <input type=\"checkbox\" ng-model=\"checkboxes[$index]\" ng-change=\"sendCheckboxState()\"\n      ng-value=\"n\">\n    </label>\n  </div>\n</div>\n\n<script>\n  (function(scope) {\n    // Initialisieren der Checkboxen, falls msg.payload.checkboxes verfügbar ist\n    scope.$watch('msg.payload', function(data) {\n      if (data && data.checkboxes) {\n        scope.checkboxes = data.checkboxes;  // Setze den Zustand der Checkboxen\n      } else {\n        scope.checkboxes = new Array(24).fill(false);  // Standard: Alle auf false setzen\n      }\n    });\n\n    // Funktion, um den Zustand der Checkboxen zu senden\n    scope.sendCheckboxState = function() {\n      // Prüfen, ob der Zustand der Checkboxen wirklich geändert wurde\n      var checkboxState = scope.checkboxes;  \n      \n      // Debug-Ausgabe: Ausgabe der geänderten Checkboxen im Debug-Fenster\n      scope.send({ payload: { checkboxes: scope.checkboxes, debug: \"Checkbox Zustand geändert\" } });\n      \n      // Sende die geänderten Checkboxen als msg an den Flow\n      scope.send({ payload: { checkboxes: checkboxState } });\n    };\n  })(scope);\n</script>\n","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":true,"templateScope":"local","className":"","x":570,"y":5860,"wires":[["6d20da959fdcff83","19885be3f274c3b2"]]},{"id":"6eba7a2c7346edac","type":"inject","z":"d1395164b4eec73e","name":"load saved data","props":[{"p":"payload.checkboxes","v":"checkboxes","vt":"flow"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":420,"y":5800,"wires":[["af86bf98ca546101"]]},{"id":"6d20da959fdcff83","type":"debug","z":"d1395164b4eec73e","name":"debug 2578","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":750,"y":5960,"wires":[]},{"id":"19885be3f274c3b2","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"checkboxes","pt":"flow","to":"payload.checkboxes","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":5880,"wires":[[]]},{"id":"472a29f10598521a","type":"ui_group","name":"Awattar_Group","tab":"2dde8bcb178d77da","order":2,"disp":true,"width":"15","collapse":false,"className":""},{"id":"2dde8bcb178d77da","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
<div style="display: flex; flex-wrap: wrap; gap: 3px;padding-left: 35px;">
  <div ng-repeat="n in msg.payload.checkboxes track by $index">
    <label>
      <input type="checkbox" ng-model="checkboxes[$index]" ng-change="sendCheckboxState()"
      ng-value="n">
    </label>
  </div>
</div>

i created my own input data not sure if it is the same as yours.

it says in line 4: invalid character in attribute name

found the error: a " to much before ng-value.
Unfortunately it does not solve my problem.
I tried to find the error for so many days but nothing.
Do you see another error maybe?

When I change a checkbox state in dashboard it is quickly marked then deleted when my 5 second trigger comes up

Please supply a simple flow with minimal nodes that shows your issue. As this is the first time you mention a 5 second trigger.

This trigger should possible contain the update checkbox values, with out all the info and a working example flow showing your issue it is really hard to help.

I would really like to show the complete flow to you, but I do not have permission to as I am new to this forum they say. Do you know another way to send the flow to you?

You can export an entire flow from the editor via ctrl e. Clicking "compact" will allow it to post into the forum as a single line (no carriage returns)

You can paste it here by clicking the </> button and ctrl v to replace the highlighted "type or paste code here"

It might occasionally give an error, for example if your flow is unusually large. In that case either simplify the flow or else save the flow somewhere online and post a link.
As far as I know, you can post code like this, also images (copy the image and ctrl v into the forum edit window), right from your first forum post.
Edit - a screen capture of your editor would help us understand the extent of flow to accompany the export.

However, we do not want to see the whole flow, we want a small flow that shows the problem, so we can test it ourselves.

[{"id":"af86bf98ca546101","type":"ui_template","z":"38565ad851da076a","group":"472a29f10598521a","name":"Checkboxes Akku","order":6,"width":"12","height":"1","format":"<!--\n<div style=\"display: flex; flex-wrap: wrap; gap: 3px;padding-left: 35px;\">\n  <div ng-repeat=\"n in [].constructor(24) track by $index\">\n    <label>\n      <input type=\"checkbox\" ng-model=\"checkboxes[$index]\" ng-change=\"sendCheckboxState()\">\n    </label>\n  </div>\n</div>\n-->\n\n<div style=\"display: flex; flex-wrap: wrap; gap: 3px;padding-left: 35px;\">\n  <div ng-repeat=\"n in msg.payload.checkboxes track by $index\">\n    <label>\n      <input type=\"checkbox\" ng-model=\"checkboxes[$index]\" ng-change=\"sendCheckboxState()\" ng-value=\"n\">\n    </label>\n  </div>\n</div>\n\n\n\n<script>\n  (function(scope) {\n    // Initialisieren der Checkboxen, falls msg.payload.checkboxes verfügbar ist\n    scope.$watch('msg.payload', function(data) {\n      if (data && data.checkboxes) {\n        scope.checkboxes = data.checkboxes;  // Setze den Zustand der Checkboxen\n      } else {\n        scope.checkboxes = new Array(24).fill(false);  // Standard: Alle auf false setzen\n      }\n    });\n\n    // Funktion, um den Zustand der Checkboxen zu senden\n    scope.sendCheckboxState = function() {\n      // Prüfen, ob der Zustand der Checkboxen wirklich geändert wurde\n      var checkboxState = scope.checkboxes;  \n      \n      // Debug-Ausgabe: Ausgabe der geänderten Checkboxen im Debug-Fenster\n      scope.send({ payload: { checkboxes: scope.checkboxes, debug: \"Checkbox Zustand geändert\" } });\n      \n      // Sende die geänderten Checkboxen als msg an den Flow\n      scope.send({ payload: { checkboxes: checkboxState } });\n    };\n  })(scope);\n</script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":890,"y":360,"wires":[["e171cefbae2babe1"]]},{"id":"c66e7e564331dc31","type":"function","z":"38565ad851da076a","name":"","func":"var FL_Strompreise24 = flow.get(\"FL_Strompreise24\") || [];\nvar FL_Stunden24 = flow.get(\"FL_Stunden24\") || [];\nvar FL_CheckboxState = flow.get(\"FL_CheckboxState\") || new Array(24).fill(false);\n\nnode.warn(\"Empfangene msg.payload: \" + JSON.stringify(msg.payload));\n\n\nif (msg.payload && msg.payload.data && Array.isArray(msg.payload.data)) {\n    node.warn(\"Neue Daten empfangen, aktualisiere Strompreise...\");\n\n    FL_Strompreise24 = [];\n    FL_Stunden24 = [];\n\n    msg.payload.data.forEach((entry) => {\n        FL_Strompreise24.push(entry.marketprice / 10);\n        let date = new Date(entry.start_timestamp);\n        FL_Stunden24.push(date.getHours() + \":\" + (\"0\" + date.getMinutes()).slice(-2));\n    });\n\n    flow.set(\"FL_Strompreise24\", FL_Strompreise24);\n    flow.set(\"FL_Stunden24\", FL_Stunden24);\n\n    FL_CheckboxState = new Array(24).fill(false);\n    let indexedPrices = FL_Strompreise24.map((price, index) => ({ price, index }));\n    indexedPrices.sort((a, b) => a.price - b.price);\n\n    let lowestIndices = indexedPrices.slice(0, 4).map(entry => entry.index);\n    lowestIndices.forEach((index) => {\n        FL_CheckboxState[index] = true;\n    });\n\n    flow.set(\"FL_CheckboxState\", FL_CheckboxState);\n}\n\nif (msg.payload && msg.payload !== \"\") {\n    //node.warn(\"Trigger: Jede Sekunde, prüfe aktuelle Checkbox...\");\n \n    if (FL_Strompreise24.length > 0 && FL_Stunden24.length > 0) {\n        let now = new Date();\n        let currentHour = now.getHours();\n        let AkkuLaden = FL_CheckboxState[currentHour] ? 1 :0;\n\n        //node.warn(\"Checkboxen: \" + FL_CheckboxState);\n        //node.warn(\"Akkuladen: \" + AkkuLaden);\n        //node.warn(\"akt.Stunde: \" + currentHour);\n\n        let textOutput = {\n            payload: AkkuLaden ? \"Akku lädt\" : \"Akku wird nicht geladen\"\n        };\n\n        let chartOutput = {\n            payload: [{\n                series: [\"Strompreise\"],\n                data: [FL_Strompreise24],\n                labels: FL_Stunden24\n            }]\n        };\n\n        let checkboxOutput = {\n            payload: {\n                FL_Strompreise24: FL_Strompreise24,\n                FL_Stunden24: FL_Stunden24,\n                checkboxes: FL_CheckboxState\n            }\n        };\n\n        flow.set(\"FL_CheckboxState\", FL_CheckboxState);\n        flow.set(\"AkkuLaden\", AkkuLaden);\n\n        node.send([chartOutput, checkboxOutput, textOutput]);\n        //return [chartOutput, checkboxOutput, textOutput];\n    } else {\n        node.warn(\"Fehler: Keine gültigen Strompreise oder Stunden verfügbar!\");\n        return [null, null, null];\n    }\n} else {\n    node.warn(\"Fehler: Kein gültiger Trigger empfangen\");\n    return null;\n}\n","outputs":3,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":680,"y":340,"wires":[["97c93b6a5a4f021c"],["af86bf98ca546101"],["f179424e292e9072"]]},{"id":"37a5e4cee357045b","type":"http request","z":"38565ad851da076a","name":"Preise von awattar laden","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://api.awattar.at/v1/marketdata?start={{payload}}","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":510,"y":260,"wires":[["8b6ca85de65430d3","c66e7e564331dc31"]]},{"id":"6b43156f871e2d4c","type":"inject","z":"38565ad851da076a","name":"5 sek","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"5","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":450,"y":140,"wires":[["c66e7e564331dc31"]]},{"id":"97c93b6a5a4f021c","type":"ui_chart","z":"38565ad851da076a","name":"","group":"472a29f10598521a","order":5,"width":"12","height":"4","label":"Strompreise","chartType":"bar","legend":"false","xformat":"auto","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":true,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":870,"y":320,"wires":[[]]},{"id":"f179424e292e9072","type":"ui_text","z":"38565ad851da076a","group":"472a29f10598521a","order":7,"width":0,"height":0,"name":"Akku lädt?","label":"text","format":"{{msg.payload}}","layout":"row-spread","className":"","style":false,"font":"","fontSize":16,"color":"#000000","x":1030,"y":180,"wires":[]},{"id":"6be2883865cdd224","type":"function","z":"38565ad851da076a","name":"epoch_seconds","func":"// Holen des aktuellen Datums\nlet now = new Date();\n\n// Setze die Uhrzeit auf 00:00:00 UTC\nlet startOfDay = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 0, 0, 0));\n\n// Berechne die epoch seconds für den Beginn des aktuellen Tages\nlet epochMilliSeconds = Math.floor(startOfDay.getTime());\n\n// Setze die epochSeconds in die msg.payload für den nächsten Node\nmsg.payload = epochMilliSeconds;\nreturn msg;\n\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":260,"wires":[["37a5e4cee357045b","f9473b51329b3e04"]]},{"id":"277a00131d48d196","type":"inject","z":"38565ad851da076a","name":"alle 24h aktualisieren","props":[],"repeat":"18000","crontab":"","once":true,"onceDelay":0.1,"topic":"","x":120,"y":120,"wires":[["6be2883865cdd224"]]},{"id":"8bf5e1d3f7417d8b","type":"ui_button","z":"38565ad851da076a","name":"","group":"472a29f10598521a","order":4,"width":0,"height":0,"passthru":false,"label":"Button-Trigger ","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"trigger","payloadType":"str","topic":"topic","topicType":"msg","x":140,"y":80,"wires":[["6be2883865cdd224"]]},{"id":"472a29f10598521a","type":"ui_group","name":"Awattar_Group","tab":"2dde8bcb178d77da","order":2,"disp":true,"width":"15","collapse":false,"className":""},{"id":"2dde8bcb178d77da","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Save the check box states after the template. Then do not overwrite them when you create them again in the function node.

e.g.

[{"id":"277a00131d48d196","type":"inject","z":"d1395164b4eec73e","name":"alle 24h aktualisieren","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":880,"y":5600,"wires":[["6be2883865cdd224"]]},{"id":"6be2883865cdd224","type":"function","z":"d1395164b4eec73e","name":"epoch_seconds","func":"// Holen des aktuellen Datums\nlet now = new Date();\n\n// Setze die Uhrzeit auf 00:00:00 UTC\nlet startOfDay = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 0, 0, 0));\n\n// Berechne die epoch seconds für den Beginn des aktuellen Tages\nlet epochMilliSeconds = Math.floor(startOfDay.getTime());\n\n// Setze die epochSeconds in die msg.payload für den nächsten Node\nmsg.payload = epochMilliSeconds;\nreturn msg;\n\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":940,"y":5740,"wires":[["37a5e4cee357045b"]]},{"id":"37a5e4cee357045b","type":"http request","z":"d1395164b4eec73e","name":"Preise von awattar laden","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://api.awattar.at/v1/marketdata?start={{payload}}","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":1170,"y":5740,"wires":[["aedcab69fdef6fac","c66e7e564331dc31"]]},{"id":"aedcab69fdef6fac","type":"debug","z":"d1395164b4eec73e","name":"debug 2","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1260,"y":5660,"wires":[]},{"id":"c66e7e564331dc31","type":"function","z":"d1395164b4eec73e","name":"","func":"var FL_Strompreise24 = flow.get(\"FL_Strompreise24\") || [];\nvar FL_Stunden24 = flow.get(\"FL_Stunden24\") || [];\nvar FL_CheckboxState = flow.get(\"FL_CheckboxState\") || new Array(24).fill(false);\n\nnode.warn(\"Empfangene msg.payload: \" + JSON.stringify(msg.payload));\n\n\nif (msg.payload && msg.payload.data && Array.isArray(msg.payload.data)) {\n    node.warn(\"Neue Daten empfangen, aktualisiere Strompreise...\");\n\n    FL_Strompreise24 = [];\n    FL_Stunden24 = [];\n\n    msg.payload.data.forEach((entry) => {\n        FL_Strompreise24.push(entry.marketprice / 10);\n        let date = new Date(entry.start_timestamp);\n        FL_Stunden24.push(date.getHours() + \":\" + (\"0\" + date.getMinutes()).slice(-2));\n    });\n\n    flow.set(\"FL_Strompreise24\", FL_Strompreise24);\n    flow.set(\"FL_Stunden24\", FL_Stunden24);\n\n    //FL_CheckboxState = new Array(24).fill(false);\n    let indexedPrices = FL_Strompreise24.map((price, index) => ({ price, index }));\n    indexedPrices.sort((a, b) => a.price - b.price);\n\n    let lowestIndices = indexedPrices.slice(0, 4).map(entry => entry.index);\n    lowestIndices.forEach((index) => {\n        FL_CheckboxState[index] = true;\n    });\n\n    flow.set(\"FL_CheckboxState\", FL_CheckboxState);\n}\n\nif (msg.payload && msg.payload !== \"\") {\n    //node.warn(\"Trigger: Jede Sekunde, prüfe aktuelle Checkbox...\");\n \n    if (FL_Strompreise24.length > 0 && FL_Stunden24.length > 0) {\n        let now = new Date();\n        let currentHour = now.getHours();\n        let AkkuLaden = FL_CheckboxState[currentHour] ? 1 :0;\n\n        //node.warn(\"Checkboxen: \" + FL_CheckboxState);\n        //node.warn(\"Akkuladen: \" + AkkuLaden);\n        //node.warn(\"akt.Stunde: \" + currentHour);\n\n        let textOutput = {\n            payload: AkkuLaden ? \"Akku lädt\" : \"Akku wird nicht geladen\"\n        };\n\n        let chartOutput = {\n            payload: [{\n                series: [\"Strompreise\"],\n                data: [FL_Strompreise24],\n                labels: FL_Stunden24\n            }]\n        };\n\n        let checkboxOutput = {\n            payload: {\n                FL_Strompreise24: FL_Strompreise24,\n                FL_Stunden24: FL_Stunden24,\n                checkboxes: FL_CheckboxState\n            }\n        };\n\n        flow.set(\"FL_CheckboxState\", FL_CheckboxState);\n        flow.set(\"AkkuLaden\", AkkuLaden);\n\n        node.send([chartOutput, checkboxOutput, textOutput]);\n        //return [chartOutput, checkboxOutput, textOutput];\n    } else {\n        node.warn(\"Fehler: Keine gültigen Strompreise oder Stunden verfügbar!\");\n        return [null, null, null];\n    }\n} else {\n    node.warn(\"Fehler: Kein gültiger Trigger empfangen\");\n    return null;\n}\n","outputs":3,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1340,"y":5820,"wires":[[],["af86bf98ca546101"],[]]},{"id":"6b43156f871e2d4c","type":"inject","z":"d1395164b4eec73e","name":"5 sek","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":1090,"y":5800,"wires":[["c66e7e564331dc31"]]},{"id":"af86bf98ca546101","type":"ui_template","z":"d1395164b4eec73e","group":"472a29f10598521a","name":"Checkboxes Akku","order":6,"width":"12","height":"1","format":"<!--\n<div style=\"display: flex; flex-wrap: wrap; gap: 3px;padding-left: 35px;\">\n  <div ng-repeat=\"n in [].constructor(24) track by $index\">\n    <label>\n      <input type=\"checkbox\" ng-model=\"checkboxes[$index]\" ng-change=\"sendCheckboxState()\">\n    </label>\n  </div>\n</div>\n-->\n\n<div style=\"display: flex; flex-wrap: wrap; gap: 3px;padding-left: 35px;\">\n  <div ng-repeat=\"n in msg.payload.checkboxes track by $index\">\n    <label>\n      <input type=\"checkbox\" ng-model=\"checkboxes[$index]\" ng-change=\"sendCheckboxState()\" ng-value=\"n\">\n    </label>\n  </div>\n</div>\n\n\n\n<script>\n  (function(scope) {\n    // Initialisieren der Checkboxen, falls msg.payload.checkboxes verfügbar ist\n    scope.$watch('msg.payload', function(data) {\n      if (data && data.checkboxes) {\n        scope.checkboxes = data.checkboxes;  // Setze den Zustand der Checkboxen\n      } else {\n        scope.checkboxes = new Array(24).fill(false);  // Standard: Alle auf false setzen\n      }\n    });\n\n    // Funktion, um den Zustand der Checkboxen zu senden\n    scope.sendCheckboxState = function() {\n      // Prüfen, ob der Zustand der Checkboxen wirklich geändert wurde\n      var checkboxState = scope.checkboxes;  \n      \n      // Debug-Ausgabe: Ausgabe der geänderten Checkboxen im Debug-Fenster\n      scope.send({ payload: { checkboxes: scope.checkboxes, debug: \"Checkbox Zustand geändert\" } });\n      \n      // Sende die geänderten Checkboxen als msg an den Flow\n      scope.send({ payload: { checkboxes: checkboxState } });\n    };\n  })(scope);\n</script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":1550,"y":5840,"wires":[["4464b15da8c197e9","f533b1489dd674e1"]]},{"id":"4464b15da8c197e9","type":"debug","z":"d1395164b4eec73e","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1740,"y":5840,"wires":[]},{"id":"f533b1489dd674e1","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"FL_CheckboxState","pt":"flow","to":"payload.checkboxes","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1740,"y":5780,"wires":[[]]},{"id":"472a29f10598521a","type":"ui_group","name":"Awattar_Group","tab":"2dde8bcb178d77da","order":2,"disp":true,"width":"15","collapse":false,"className":""},{"id":"2dde8bcb178d77da","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

thank you very much for your help. It nearly works. The only thing, which does not work is, when a new 24hrs trigger comes, the manually set checkboxes are not reset. after each 24hrs I would like to clear all 24 checkboxes and set the 4 lowest automatically again. All others should be unchecked.

You will need to alter your function node to do this, not sure how as the function is fairly large and I do not have time to break it down. Possible a flag in the 24hour trigger to reset the checkbox context.