Dynamic Battery Charging Control for BYD Battery with Tibber Prices and Solar Forecast (Akku-PV Control)
This flow automatically optimizes the charging behavior of your BYD home battery (Akku-PV) based on:
Tibber dynamic electricity prices
Solar production forecasts (via forecast.solar API)
Current State of Charge (SoC) of your battery
Wallbox (EV Charger) status to avoid conflicts with car charging
Customizable load targets (e.g., charge to 70/80/85/90 % depending on solar forecast for the next day)
It allows the battery to charge from the grid only when cheap electricity and low solar production are expected, preventing grid charging when it’s not economically viable or when enough solar surplus is forecasted.
Additionally, the system uses Alexa voice announcements to inform the household when grid charging starts.
✅ Main Features: Dynamic Price-Optimized Charging (Tibber Prices): The flow compares current price spread (Δ ≥ 10 Cent) and only triggers grid charging if economic conditions are met.
Solar Forecast Based Limitation: Grid charging will only be allowed if next-day solar production is forecasted below 20 kWh.
State of Charge Target Adaptation: Automatically adjusts charge target (SOC) between 70%, 80%, 85%, or 90% depending on total expected solar energy.
Prevention of Overcharging during Car Charging: Checks that both Wallbox chargers are idle before allowing battery grid charging.
Failsafe Checks: Battery state, grid charging state, and wallbox load status are checked before execution.
Control over Home Assistant Scripts: Triggers custom BYD charging scripts in Home Assistant (script.byd_force_charging, script.byd_reset_charging).
Real-Time Feedback: Writes battery charging plans to a Home Assistant sensor entity for visualization and monitoring.
Rate Limiting on Solar Forecast API: Includes built-in rate limiting to avoid exceeding forecast.solar free API limits (1 request per 15 minutes).
Debugging: Comprehensive debug outputs at all critical decision points.
[{"id":"93f485839dfa27a8","type":"subflow","name":"Solar forecast","info":"This subflow uses the http request node to fetch solar forecasts for geographical positions, using the API from https://forecast.solar/. Please check their website and consider getting a paid account.\n\nDo note that, on a free account, you are limited in the number of requests to do. Also note that the data only gets updated once every 15 minutes, so there is no reason to query more often. There is rate limiting built in the subflow not to perform requests more than once every 15 minutes.\n\n# Configuration\n\nIt uses the parameters as described on: http://doc.forecast.solar/doku.php\n\n - `:apikey` - personal API key for registered users\n - `:lat` - latitude of location, -90 (south) … 90 (north); Internal precission is 0.0001 or abt. 10 m\n - `:lon` - longitude of location, -180 (west) … 180 (east); Internal precission is 0.0001 or abt. 10 m\n - `:dec` - plane declination, 0 (horizontal) … 90 (vertical); Internal precission is integer\n - `:az` - plane azimuth, -180 … 180 (-180 = north, -90 = east, 0 = south, 90 = west, 180 = north); Internal precission is integer\n - `:kwp` - installed modules power in kilo watt peak (kWp)\n\nYou can choose between 3 different type of requests. Note that only `estimate` is available on the free plan.\n\n- `estimate` - this is the forecasted estimate that your panels should produce (given the right parameter settings)\n- `history` - historycal data\n- `clear sky` - estimate given if there would be a clear sky tomorrow\n\nIn case of estimates, one of the following options can be selected:\n- `watts` - Watts (power) average for the period\n- `watthours/period` - Watt hours (energy) for the period\n- `watthours` - Watt hours (energy) summarized over the day\n- `watthours/day` - Watt hours (energy) summarized for each day\n\nFor the graph output there are some extra settings available:\n\n- _Output in kWh_ - when checked output can be set to kWh instead of Wh\n- _Show todays forecast_ - whether or not to include todays forecast\n- _Days to forecast_ - the number of days to forecast (excluding today). Note that you can not get more days forecasted than your API key allows.\n- _Widen graph_ - widen the graph to only show non-zero values\n- _Show day instead of date_ - Show the day instead of the date in the series and labels\n\n# Input \n\nThe input is for triggering the solar forecast request. \nIt triggers when injecting a message into the node.\n\n# Output\n\nThere are two outputs. The first output is an object with the result and a status message stored into the `msg.payload`.\n\nMost important is the `msg.payload.result`, which contains the estimated production of the panels. E.g.:\n\n```\npayload: object\n result: object\n 2022-11-28: 23\n 2022-11-29: 35\n```\n\nThe `msg.payload.message` gives information on how successful the query was, the exitcode of the query and the status of the rate limit (how many queries you have left).\n\nThe **second** output can be directly linked to a line or a bar chart, quickly giving a once-glance overview for the predicted forecast.\n\n# Status\n\nInitially the status of the note will be a blue dot, showing \"_Unknown limit_\", as it is unaware of the set ratelmits. After the first request, the returned ratelimit will be put in the text in the form of `remaining/limit`. If more than half the limit is remaining, the dot will be green. If less then half the limit is remaining, the dot will be yellow. If no limit is left, the dot will turn red.\nPlease keep in mind that the ratelimit will be reset after one hour, so you can send a new request after that hour.\n\nIf something is wrong in the API request, the dot will turn red\nand the message will contain the msg.payload with the error. This\nhappens typically when the API is temporally down for maintenance.","category":"","in":[{"x":240,"y":100,"wires":[{"id":"c8dc6aa14b9f3e92"}]}],"out":[{"x":760,"y":260,"wires":[{"id":"2f42837904c91d73","port":0},{"id":"fcc8d69a3ab88e6d","port":0}]},{"x":770,"y":340,"wires":[{"id":"5b0a430fb61e70e7","port":0}]}],"env":[{"name":"latitude","type":"num","value":"51.3","ui":{"icon":"font-awesome/fa-location-arrow","label":{"en-US":"Latitude"},"type":"input","opts":{"types":["num"]}}},{"name":"longitude","type":"num","value":"5.6","ui":{"icon":"font-awesome/fa-location-arrow","label":{"en-US":"Longitude"},"type":"input","opts":{"types":["num"]}}},{"name":"declination","type":"num","value":"37","ui":{"icon":"font-awesome/fa-chevron-up","label":{"en-US":"Declination"},"type":"input","opts":{"types":["num"]}}},{"name":"azimuth","type":"num","value":"0","ui":{"icon":"font-awesome/fa-compass","label":{"en-US":"Azimuth"},"type":"spinner","opts":{"min":-180,"max":180}}},{"name":"modules power","type":"num","value":"1","ui":{"icon":"font-awesome/fa-power-off","label":{"en-US":"Modules power (kWp)"},"type":"input","opts":{"types":["num"]}}},{"name":"apikey","type":"cred","ui":{"icon":"font-awesome/fa-key","label":{"en-US":"API key"},"type":"input","opts":{"types":["cred"]}}},{"name":"type","type":"str","value":"estimate","ui":{"label":{"en-US":"Type"},"type":"select","opts":{"opts":[{"l":{"en-US":"Estimate"},"v":"estimate"},{"l":{"en-US":"History"},"v":"history"},{"l":{"en-US":"Clear sky"},"v":"clearsky"}]}}},{"name":"watt","type":"str","value":"watts","ui":{"icon":"font-awesome/fa-question-circle-o","label":{"en-US":"Watt"},"type":"select","opts":{"opts":[{"l":{"en-US":"Watts (power) average for the period"},"v":"watts"},{"l":{"en-US":"Watt hours (energy) for the period"},"v":"watthours/period"},{"l":{"en-US":"Watt hours (energy) summarized over the day"},"v":"watthours"},{"l":{"en-US":"Watt hours (energy) summarized for each day"},"v":"watthours/day"}]}}},{"name":"kwhoutput","type":"bool","value":"false","ui":{"label":{"en-US":"Output in kWh (in the graph)"},"type":"checkbox"}},{"name":"showtoday","type":"bool","value":"true","ui":{"label":{"en-US":"Show todays forecast"},"type":"checkbox"}},{"name":"daystoforecast","type":"str","value":"-1","ui":{"label":{"en-US":"Days to forecast"},"type":"select","opts":{"opts":[{"l":{"en-US":"Max"},"v":"-1"},{"l":{"en-US":"0"},"v":"0"},{"l":{"en-US":"1"},"v":"1"},{"l":{"en-US":"2"},"v":"2"},{"l":{"en-US":"3"},"v":"3"},{"l":{"en-US":"4"},"v":"4"},{"l":{"en-US":"5"},"v":"5"},{"l":{"en-US":"6"},"v":"6"}]}}},{"name":"widengraph","type":"bool","value":"true","ui":{"label":{"en-US":"Widen graph"},"type":"checkbox"}},{"name":"showday","type":"bool","value":"false","ui":{"label":{"en-US":"Show day instead of date"},"type":"checkbox"}}],"meta":{"module":"Solar Forecast","version":"0.0.12","author":"[email protected]","desc":"Get solar forecasting per location","keywords":"solar,forecast,api","license":"GPL-3.0"},"color":"#FFCC66","inputLabels":["trigger"],"outputLabels":["output","graph"],"icon":"font-awesome/fa-sun-o","status":{"x":680,"y":560,"wires":[{"id":"1bfc1cde3ee94e4b","port":0},{"id":"a798fbe66cf133d5","port":0}]}},{"id":"c706820c0d61f023","type":"http request","z":"93f485839dfa27a8","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":390,"y":180,"wires":[["1b5ccaa05d54f7c3"]]},{"id":"b9488734852cd0ca","type":"function","z":"93f485839dfa27a8","name":"create forecast.solar url","func":"msg.url = 'https://api.forecast.solar/';\n\nif (env.get('apikey')) {\n msg.url += env.get('apikey') + '/';\n }\n\nmsg.url += env.get('type') + '/';\n\nmsg.url += env.get('watt') + '/';\n\nmsg.url += env.get('latitude') + '/' +\n env.get('longitude') + '/' +\n env.get('declination') + '/' +\n env.get('azimuth') + '/' +\n env.get('modules power');\n\nmsg.topic = 'solar forecast: '+(env.get('type') || '');\nmsg.topic += (' '+env.get('watt') || '');\nif (env.get('kwhoutput')) {\n msg.topic += ' (kWh)';\n}\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":630,"y":100,"wires":[["975daf96f15cfb61"]]},{"id":"1b5ccaa05d54f7c3","type":"json","z":"93f485839dfa27a8","name":"Convert to json","property":"payload","action":"","pretty":false,"x":680,"y":180,"wires":[["e718a22973cc2864"]]},{"id":"559391d1288f762a","type":"function","z":"93f485839dfa27a8","name":"update ratelimit","func":"var remaining = msg.payload.message.ratelimit.remaining || 0;\nvar limit = msg.payload.message.ratelimit.limit;\n\nflow.set('forecast.solar.ratelimit.remaining', remaining)\nflow.set('forecast.solar.ratelimit.limit', limit)\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":480,"wires":[["e56826252134b93a"]]},{"id":"e718a22973cc2864","type":"link out","z":"93f485839dfa27a8","name":"link out 1","mode":"link","links":["3fa24f2d08195961","0a20e852662c8cec"],"x":815,"y":180,"wires":[]},{"id":"3fa24f2d08195961","type":"link in","z":"93f485839dfa27a8","name":"link in 1","links":["e718a22973cc2864"],"x":385,"y":480,"wires":[["559391d1288f762a"]]},{"id":"0a20e852662c8cec","type":"link in","z":"93f485839dfa27a8","name":"link in 2","links":["e718a22973cc2864"],"x":225,"y":260,"wires":[["fcc8d69a3ab88e6d"]]},{"id":"4734b6f403e1f03e","type":"inject","z":"93f485839dfa27a8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":530,"y":440,"wires":[["e56826252134b93a"]]},{"id":"c8dc6aa14b9f3e92","type":"delay","z":"93f485839dfa27a8","name":"1 msg/15 minutes","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"15","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":390,"y":100,"wires":[["b9488734852cd0ca"]]},{"id":"1bfc1cde3ee94e4b","type":"function","z":"93f485839dfa27a8","name":"update status","func":"var remaining = flow.get('forecast.solar.ratelimit.remaining') || -1;\nvar limit = flow.get('forecast.solar.ratelimit.limit') || -1\n\nvar text = remaining.toString() + '/' + limit.toString();\nvar fill = \"green\";\n\nif (remaining == 0) {\n fill = \"red\";\n text = \"Limit used\";\n}\n\nif (remaining > 0 && remaining < limit / 2) {\n fill = \"yellow\"\n}\n\nif (remaining == -1 ) {\n fill = \"blue\"\n text = \"Limits unknown\"\n}\n\nmsg.payload = ({ fill: fill, text: text });\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":580,"wires":[[]]},{"id":"a18e96179ec2d987","type":"function","z":"93f485839dfa27a8","name":"Create graph output","func":"var m = {};\nm.labels = [];\nm.data = [];\n\nm.series = [];\nm.data = [];\nm.labels = [];\n\nfor (let j = 0; j <= msg.days; j++) {\n m.data[j] = [];\n}\n\nif (msg.watt === 'watt_hours_day') {\n var i = 0;\n if (msg.kwhoutput) {\n m.series.push(\"kWh per day\");\n } else {\n m.series.push(\"Watt hours per day\");\n }\n for (const key in msg.payload.result) {\n m.labels.push(key);\n if (msg.kwhoutput) {\n m.data[i] = +(Math.round(msg.payload.result[key]/100)*.1).toFixed(1);\n } else {\n m.data[i] = msg.payload.result[key];\n }\n i++;\n }\n m.data = [m.data];\n return { payload: [m] };\n}\n\nfor (let i = 0; i <= 23; i++) {\n\n m.labels.push(i.toString()+':00');\n if (msg.resolution === 4) {\n m.labels.push(i.toString()+':15');\n }\n if (msg.resolution === 2 || msg.resolution == 4) {\n m.labels.push(i.toString()+':30');\n }\n if (msg.resolution === 4) {\n m.labels.push(i.toString()+':45');\n }\n\n for (let j = 0; j <= msg.days; j++) {\n m.data[j].push(0);\n if (msg.resolution === 4) {\n m.data[j].push(0)\n }\n if (msg.resolution === 2 || msg.resolution == 4) {\n m.data[j].push(0)\n }\n if (msg.resolution === 4) {\n m.data[j].push(0)\n }\n\n }\n}\n\nvar offset = 0;\nfor (const key in msg.payload.result) {\n var d = new Date(key)\n if (m.series.indexOf(d.toISOString().split('T')[0]) === -1) {\n m.series.push(d.toISOString().split('T')[0])\n }\n\n var h = d.getHours();\n var minutes = d.getMinutes();\n\n if (minutes === 0 ) {\n offset = 0;\n } else {\n offset++;\n }\n\n if (msg.kwhoutput) {\n m.data[m.series.length - 1][h*msg.resolution+offset] = +(Math.round(msg.payload.result[key]/100)*.1).toFixed(1);\n } else {\n m.data[m.series.length - 1][h*msg.resolution+offset] = msg.payload.result[key];\n }\n}\n\nif (msg.watt === 'watt_hours') {\n for (const i in m.data) {\n let x = m.data[i][0]\n for (const d in m.data[i]) {\n if ( x > m.data[i][d]) {\n m.data[i][d] = x \n }\n x = m.data[i][d]\n }\n }\n}\n\nreturn { payload: [m] };\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":340,"wires":[["5b0a430fb61e70e7"]]},{"id":"975daf96f15cfb61","type":"link out","z":"93f485839dfa27a8","name":"link out 7","mode":"link","links":["14f2e68e572f4ef8"],"x":805,"y":100,"wires":[]},{"id":"14f2e68e572f4ef8","type":"link in","z":"93f485839dfa27a8","name":"link in 18","links":["975daf96f15cfb61"],"x":245,"y":180,"wires":[["c706820c0d61f023"]]},{"id":"c4307905e114824f","type":"catch","z":"93f485839dfa27a8","name":"","scope":null,"uncaught":false,"x":260,"y":440,"wires":[["f427f19392c399ce"]]},{"id":"e56826252134b93a","type":"link out","z":"93f485839dfa27a8","name":"link out 8","mode":"link","links":["dbaf8f5f5a920686"],"x":685,"y":480,"wires":[]},{"id":"dbaf8f5f5a920686","type":"link in","z":"93f485839dfa27a8","name":"link in 19","links":["e56826252134b93a"],"x":385,"y":580,"wires":[["1bfc1cde3ee94e4b"]]},{"id":"f427f19392c399ce","type":"link out","z":"93f485839dfa27a8","name":"link out 9","mode":"link","links":["2ded0c14a222b4d9","2f42837904c91d73"],"x":375,"y":440,"wires":[]},{"id":"2ded0c14a222b4d9","type":"link in","z":"93f485839dfa27a8","name":"link in 20","links":["f427f19392c399ce"],"x":385,"y":540,"wires":[["a798fbe66cf133d5"]]},{"id":"a798fbe66cf133d5","type":"function","z":"93f485839dfa27a8","name":"Set error status","func":"node.warn(msg.payload)\nmsg.payload = ({ fill: \"red\", text: msg.payload });\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":540,"wires":[[]]},{"id":"2f42837904c91d73","type":"link in","z":"93f485839dfa27a8","name":"link in 21","links":["f427f19392c399ce"],"x":665,"y":280,"wires":[[]]},{"id":"fcc8d69a3ab88e6d","type":"function","z":"93f485839dfa27a8","name":"Processed info","func":"msg.resolution = 60;\nmsg.days = 1;\nmsg.type = env.get('type');\nmsg.watt = env.get('watt');\nmsg.kwhoutput = env.get('kwhoutput');\n\nvar key1 = Object.keys(msg.payload.result)[1];\nvar key2 = Object.keys(msg.payload.result)[2];\nvar key3 = Object.keys(msg.payload.result)[Object.keys(msg.payload.result).length-1];\n\nvar d1 = new Date(key1);\nvar d2 = new Date(key2); \nvar d3 = new Date(key3);\nmsg.resolution = 3600000 / (d2.getTime() - d1.getTime());\n\nmsg.days = Math.floor((d3.getTime() - d1.getTime()) / (1000 * 3600 * 24));\n\nif (msg.watt === 'watt_hours_day') {\n msg.resolution = null;\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":260,"wires":[["a18e96179ec2d987"]],"info":"Function to process the result from forecast.solar to add\nextra information, which is handy for either graphing or\nto store in a database.\n\n\nThe extra values added:\n- `msg.resolution` - The number of measurements per hour. If\nno API key is used, this will be 1. Other values may be 2 or 4.\n- `msg.days` - The number of days in the forcast. If no API\n- key is used this will be 1. Other values may be 3 or 6."},{"id":"5b0a430fb61e70e7","type":"function","z":"93f485839dfa27a8","name":"Filter graph","func":"var forecasted = msg.payload[0].series.length;\n\nif ((Number(env.get('daystoforecast')) > -1) && (Number(env.get('daystoforecast')) < forecasted)) {\n for (let i = 1; i <= (forecasted - Number(env.get('daystoforecast'))); i++ ) {\n msg.payload[0].data.pop();\n msg.payload[0].series.pop();\n }\n}\n\nif (!env.get('showtoday')) {\n msg.payload[0].data.shift();\n msg.payload[0].series.shift();\n}\n\nif (env.get('showday')) {\n const weekday = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n msg.payload[0].labels.forEach(function (/** @type {string | number | Date} */ date, /** @type {string | number} */ index, /** @type {{ [x: string]: string; }} */ array) {\n const d = new Date(date)\n if (!isNaN(d)) {\n array[index] = weekday[d.getDay()]\n }\n })\n msg.payload[0].series.forEach(function (/** @type {string | number | Date} */ date, /** @type {string | number} */ index, /** @type {{ [x: string]: string; }} */ array) {\n const d = new Date(date)\n if (!isNaN(d)) {\n array[index] = weekday[d.getDay()]\n }\n })\n}\n\nif (env.get('widengraph')) {\n var c = msg.payload[0].labels.length;\n var x = 0;\n for (let i = 0; i < c; i++) {\n var remove = true;\n for (let d = 0; d < msg.payload[0].data.length; d++) {\n if (msg.payload[0].data[d][x] > 0) {\n remove = false;\n }\n }\n if (remove) {\n msg.payload[0].labels.splice(x, 1);\n for (let d = 0; d < msg.payload[0].data.length; d++) {\n msg.payload[0].data[d].splice(x, 1);\n }\n x--;\n }\n x++;\n }\n // Still the first and last datapoints should be zero, so\n // add those again\n msg.payload[0].labels.unshift('');\n msg.payload[0].labels.push('');\n for (let d = 0; d < msg.payload[0].data.length; d++) {\n msg.payload[0].data[d].unshift(0);\n msg.payload[0].data[d].push(0);\n } \n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":590,"y":340,"wires":[[]]},{"id":"f7092f17fe21a777","type":"debug","z":"3ab217fef43e55c3","name":"Akku-PV debug","active":false,"tosidebar":true,"console":true,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1150,"y":100,"wires":[]},{"id":"0bbfde966ca3b1a2","type":"function","z":"3ab217fef43e55c3","name":"Convert true/false to 1/0","func":"function adjustOnOffValues(msg) {\n const condition = global.get(\"pv-akku-vom-netz-bedingungen\");\n\n // Prüfen, ob die globale Bedingung true ist\n if (condition) {\n // Wenn die Bedingung erfüllt ist, behalte die ursprünglichen onOff Werte\n node.warn(\"Bedingungen erfüllt: onOff Werte bleiben unverändert.\");\n msg.payload.hours.forEach(akku => akku.onOff = akku.onOff ? \"1\" : \"0\");\n } else {\n // Setze alle onOff Werte zu \"0\", wenn die Bedingung nicht erfüllt ist (false)\n msg.payload.hours.forEach(akku => {\n akku.onOff = \"0\"; // Setzt onOff zu \"0\", unabhängig vom ursprünglichen Wert\n });\n node.warn(\"Bedingungen PV Akku vom Netz nicht erfüllt: Alle onOff Werte wurden auf '0' gesetzt.\");\n }\n\n return msg;\n}\n\nconst output = adjustOnOffValues(msg);\nreturn output;\n","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1130,"y":300,"wires":[["0f6d2edf46b378db"]]},{"id":"0f6d2edf46b378db","type":"ha-sensor","z":"3ab217fef43e55c3","name":"Preis Planung Akku-PV","entityConfig":"536cc4c3290d1e64","version":0,"state":"payload","stateType":"str","attributes":[{"property":"Schedule","value":"payload.schedule","valueType":"msg"},{"property":"Hours","value":"payload.hours","valueType":"msg"},{"property":"Control","value":"payload.hours[0].onOff","valueType":"str"},{"property":"Current","value":"payload.current","valueType":"str"}],"inputOverride":"allow","outputProperties":[],"x":1530,"y":320,"wires":[["bb6cbc2f720e2b4e"]]},{"id":"bb6cbc2f720e2b4e","type":"debug","z":"3ab217fef43e55c3","name":"powersaver_planning_akku_pv","active":false,"tosidebar":true,"console":true,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1840,"y":320,"wires":[]},{"id":"75ad5df12539cb35","type":"ps-strategy-lowest-price","z":"3ab217fef43e55c3","name":"Lowest Price Akku-PV","fromTime":"00","toTime":"00","hoursOn":"2","maxPrice":"","doNotSplit":false,"sendCurrentValueWhenRescheduling":true,"outputValueForOn":"90","outputValueForOff":"5","outputValueForOntype":"num","outputValueForOfftype":"num","outputIfNoSchedule":"false","outputOutsidePeriod":"false","contextStorage":"memory","x":900,"y":180,"wires":[["f7092f17fe21a777","49929d0a0dfe1037"],["f7092f17fe21a777","d9e042a5700e5e7c"],["0bbfde966ca3b1a2","728dc266aa12498b"]]},{"id":"237b5d211d77f810","type":"api-call-service","z":"3ab217fef43e55c3","name":"","server":"xxx","version":7,"debugenabled":false,"action":"script.byd_force_charging","floorId":[],"areaId":[],"deviceId":[],"entityId":[],"labelId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","blockInputOverrides":false,"domain":"script","service":"byd_force_charging","x":2030,"y":160,"wires":[["43fd43a4b32c0d81","0c3b2b73a9e26123"]]},{"id":"8518d5c154d32c13","type":"api-call-service","z":"3ab217fef43e55c3","name":"","server":"xxx","version":7,"debugenabled":false,"action":"script.byd_reset_charging","floorId":[],"areaId":[],"deviceId":[],"entityId":[],"labelId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","blockInputOverrides":false,"domain":"script","service":"byd_reset_charging","x":2310,"y":220,"wires":[[]]},{"id":"e35c56ee341fc7a5","type":"api-current-state","z":"3ab217fef43e55c3","name":"BYD not SOC 90","server":"xxx","version":3,"outputs":2,"halt_if":"90","halt_if_type":"num","halt_if_compare":"is_not","entity_id":"sensor.byd_minrsvpct","state_type":"num","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":1490,"y":160,"wires":[["0ce832147c815966"],[]]},{"id":"43fd43a4b32c0d81","type":"delay","z":"3ab217fef43e55c3","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"hours","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":2300,"y":160,"wires":[["934ed37ac2d276ba"]]},{"id":"0e96842dca89f452","type":"function","z":"3ab217fef43e55c3","name":"PV Akku Netz-Ladungsbedingungen 20kwh","func":"function controlEnergySystem(msg) {\n const priceData = global.get(\"TibberPriceReceiver\");\n let productionForecastData = msg.solar_forecast;\n\n if (!priceData || !productionForecastData) {\n node.error(\"Preisdaten oder Produktionsprognosedaten fehlen.\");\n return null; // Stoppt die Funktion, wenn keine Daten vorhanden sind\n }\n\n // Debug-Ausgabe zur Überprüfung der Rohdaten\n //node.warn(\"Price Data: \" + JSON.stringify(priceData));\n //node.warn(\"Production Forecast Data: \" + JSON.stringify(productionForecastData));\n\n priceData.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime());\n\n const prices = priceData.map(data => data.value);\n const maxPrice = Math.max(...prices);\n const minPrice = Math.min(...prices);\n const priceDiff = maxPrice - minPrice;\n\n // Versuchen Sie, productionForecastData in ein Array zu konvertieren\n let productionValues;\n if (typeof productionForecastData === 'string') {\n // Annahme, dass die Produktionsprognose als kommagetrennte Werte in einer Zeichenkette vorliegt\n productionValues = productionForecastData.split(',').map(value => parseFloat(value));\n } else {\n // Wenn es bereits ein Array ist, konvertieren Sie die Werte direkt\n productionValues = Object.values(productionForecastData).map(value => parseFloat(value));\n }\n\n // Überprüfen Sie, ob alle Werte gültige Zahlen sind\n if (productionValues.some(isNaN)) {\n node.error(\"Ungültige Werte in den Produktionsprognosedaten.\");\n node.warn(\"Production Values: \" + JSON.stringify(productionValues));\n return null;\n }\n\n const totalProduction = productionValues.reduce((sum, value) => sum + value, 0);\n const hours = 24;\n const averageProduction = totalProduction / hours;\n\n const averageConsumption = 1;\n const totalConsumption = averageConsumption * hours; // 24 kW\n\n // Werte auf 2 Dezimalstellen runden\n const roundedTotalProduction = totalProduction.toFixed(2);\n const roundedTotalConsumption = totalConsumption.toFixed(2);\n\n // Debug-Ausgaben hinzufügen\n //node.warn(`MaxPrice: ${maxPrice}, MinPrice: ${minPrice}, PriceDiff: ${priceDiff.toFixed(2)}`);\n //node.warn(`TotalProduction: ${roundedTotalProduction}, AverageProduction: ${averageProduction.toFixed(2)}`);\n //node.warn(`TotalConsumption: ${roundedTotalConsumption}`);\n\n if (priceDiff >= 0.10) {\n node.warn(\"PriceDiff Bedingung erfüllt\");\n } else {\n node.warn(\"PriceDiff Bedingung nicht erfüllt\");\n }\n\n if (totalProduction < 20) {\n node.warn(\"TotalProduction Bedingung erfüllt\");\n } else {\n node.warn(\"TotalProduction Bedingung nicht erfüllt\");\n }\n\n if (priceDiff >= 0.10 && totalProduction < 20) {\n //node.warn(\"Bedingungen erfüllt, Daten werden weitergeleitet.\");\n global.set(\"pv-akku-vom-netz-bedingungen\", true);\n msg.payload = true;\n return msg;\n } else {\n //node.warn(\"Bedingungen nicht erfüllt, Daten werden nicht weitergeleitet.\");\n global.set(\"pv-akku-vom-netz-bedingungen\", false);\n msg.payload = false;\n return msg;\n }\n}\n\nconst result = controlEnergySystem(msg);\nreturn result;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1320,"y":500,"wires":[["b46708017e92a6c0","b60333b307e6250f"]]},{"id":"49929d0a0dfe1037","type":"function","z":"3ab217fef43e55c3","name":"pv-akku-vom-netz-bedingungen true","func":"function forwardMessageIfConditionMet(msg) {\n // Abrufen des Werts der globalen Variable\n const condition = global.get(\"pv-akku-vom-netz-bedingungen\");\n\n // Überprüfen, ob die Bedingung true ist\n if (condition === true) {\n //node.warn(\"Globale Bedingung ist erfüllt, Nachricht wird weitergeleitet.\");\n return msg; // Weiterleiten der Nachricht, wenn die Bedingung erfüllt ist\n } else {\n //node.warn(\"Globale Bedingung ist nicht erfüllt, Nachricht wird nicht weitergeleitet.\");\n return null; // Nicht weiterleiten der Nachricht, wenn die Bedingung nicht erfüllt ist\n }\n}\n\nconst output = forwardMessageIfConditionMet(msg);\nreturn output;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1210,"y":160,"wires":[["e35c56ee341fc7a5"]]},{"id":"d9e042a5700e5e7c","type":"api-current-state","z":"3ab217fef43e55c3","name":"BYD SOC 90","server":"xxx","version":3,"outputs":2,"halt_if":"90","halt_if_type":"num","halt_if_compare":"is","entity_id":"sensor.byd_minrsvpct","state_type":"num","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":1230,"y":200,"wires":[["f2275889be79c5e7"],[]]},{"id":"ebbc6e5a0ddb0af2","type":"api-call-service","z":"3ab217fef43e55c3","name":"BYD Akku läd vom Netz with Alexa","server":"xxx","version":7,"debugenabled":false,"action":"notify.alexa_media_users_echo_dot","floorId":[],"areaId":[],"deviceId":[],"entityId":[],"labelId":[],"data":"{ \"message\": \"Alexa hier, unser BYD Akku läd günstig vom Netz!\", \"data\": { \"type\": \"announce\" }, \"target\": \"{{entity}}\" }","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","blockInputOverrides":false,"domain":"notify","service":"alexa_media_users_echo_dot","x":2620,"y":100,"wires":[[]]},{"id":"728dc266aa12498b","type":"api-current-state","z":"3ab217fef43e55c3","name":"","server":"xxx","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.solar_forecast","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"solar_forecast","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":980,"y":500,"wires":[["0e96842dca89f452"]]},{"id":"0c3b2b73a9e26123","type":"api-call-service","z":"3ab217fef43e55c3","name":"users Echo Dot Volume 5","server":"xxx","version":7,"debugenabled":false,"action":"media_player.volume_set","floorId":[],"areaId":[],"deviceId":[],"entityId":["media_player.users_echo_dot"],"labelId":[],"data":"{\"volume_level\":\"0.5\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","blockInputOverrides":false,"domain":"media_player","service":"volume_set","x":2300,"y":100,"wires":[["ebbc6e5a0ddb0af2"]]},{"id":"b60333b307e6250f","type":"ha-binary-sensor","z":"3ab217fef43e55c3","name":"pv-akku-vom-netz-bedingungen","entityConfig":"80a6d0d9529392b1","version":0,"state":"payload","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1670,"y":500,"wires":[[]]},{"id":"b46708017e92a6c0","type":"debug","z":"3ab217fef43e55c3","name":"pv-akku-vom-netz-bedingungen","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1650,"y":560,"wires":[]},{"id":"31d61679d592f2fa","type":"inject","z":"3ab217fef43e55c3","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":900,"y":580,"wires":[["728dc266aa12498b"]]},{"id":"0ce832147c815966","type":"api-current-state","z":"3ab217fef43e55c3","name":"BYD nicht 90 %","server":"xxx","version":3,"outputs":2,"halt_if":"90","halt_if_type":"num","halt_if_compare":"lt","entity_id":"sensor.byd_battery_box_premium_hv_ladezustand","state_type":"num","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":1800,"y":160,"wires":[["237b5d211d77f810"],[]]},{"id":"b18401f6ce441e21","type":"inject","z":"3ab217fef43e55c3","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":920,"y":100,"wires":[["49929d0a0dfe1037"]]},{"id":"1d0ff8a5031f6211","type":"comment","z":"3ab217fef43e55c3","name":"BYD Akku Laden nach Strompreis","info":"","x":900,"y":60,"wires":[]},{"id":"f2275889be79c5e7","type":"api-current-state","z":"3ab217fef43e55c3","name":"BYD State ist nicht Netz-Lade-Force","server":"xxx","version":3,"outputs":2,"halt_if":"0","halt_if_type":"num","halt_if_compare":"gte","entity_id":"sensor.byd_outwrte","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":1490,"y":220,"wires":[["934ed37ac2d276ba"],[]]},{"id":"934ed37ac2d276ba","type":"api-current-state","z":"3ab217fef43e55c3","name":"Wallbox Carport läd nicht","server":"xxx","version":3,"outputs":2,"halt_if":"Laden","halt_if_type":"str","halt_if_compare":"is_not","entity_id":"","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":1790,"y":220,"wires":[["f0ab60cd9f5b4483"],[]]},{"id":"f0ab60cd9f5b4483","type":"api-current-state","z":"3ab217fef43e55c3","name":"Wallbox Garage läd nicht","server":"xxx","version":3,"outputs":2,"halt_if":"Laden","halt_if_type":"str","halt_if_compare":"is_not","entity_id":"","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":2050,"y":220,"wires":[["8518d5c154d32c13"],[]]},{"id":"ae683b2e09cad373","type":"debug","z":"3ab217fef43e55c3","name":"OutputValueForOn für State of Charge Akku-PV gedacht","active":false,"tosidebar":true,"console":true,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1060,"y":660,"wires":[]},{"id":"9953188c75662c5d","type":"switch","z":"3ab217fef43e55c3","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lt","v":"10000","vt":"str"},{"t":"btwn","v":"10000","vt":"num","v2":"20000","v2t":"num"},{"t":"btwn","v":"20000","vt":"num","v2":"30000","v2t":"num"},{"t":"gt","v":"30000","vt":"str"}],"checkall":"true","repair":false,"outputs":4,"x":590,"y":780,"wires":[["b933d43f3ae968c3"],["603377ee30b11f14"],["c180044e728fe49b"],["aa432df9fe6e174a"]]},{"id":"b933d43f3ae968c3","type":"change","z":"3ab217fef43e55c3","name":"SOC 90","rules":[{"t":"set","p":"payload","pt":"msg","to":"90","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":720,"wires":[["6067d549147cfa8d"]]},{"id":"603377ee30b11f14","type":"change","z":"3ab217fef43e55c3","name":"SOC 85","rules":[{"t":"set","p":"payload","pt":"msg","to":"85","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":760,"wires":[["6067d549147cfa8d"]]},{"id":"c180044e728fe49b","type":"change","z":"3ab217fef43e55c3","name":"SOC 80","rules":[{"t":"set","p":"payload","pt":"msg","to":"80","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":800,"wires":[["6067d549147cfa8d"]]},{"id":"aa432df9fe6e174a","type":"change","z":"3ab217fef43e55c3","name":"SOC 70","rules":[{"t":"set","p":"payload","pt":"msg","to":"70","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":840,"wires":[["6067d549147cfa8d"]]},{"id":"6067d549147cfa8d","type":"function","z":"3ab217fef43e55c3","name":"Übergabe Lowest Price SOC","func":"var adaptedsoc = msg.payload;\nmsg.payload =\n{\n \"config\": {\n \"outputValueForOn\": Number(adaptedsoc),\n \"outputValueForOntype\": \"num\"\n }\n\n};\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":780,"wires":[["ae683b2e09cad373","75ad5df12539cb35"]]},{"id":"6269dd620986db6f","type":"inject","z":"3ab217fef43e55c3","name":"TibberSolarSOC 3 Nachts Tages Solar forecast","props":[{"p":"payload"}],"repeat":"","crontab":"00 03 * * *","once":true,"onceDelay":"150","topic":"","payload":"","payloadType":"date","x":240,"y":780,"wires":[["e0a87f2cad0f9668","91c912e197d3ff33"]]},{"id":"e0a87f2cad0f9668","type":"api-current-state","z":"3ab217fef43e55c3","name":"Solar forecast","server":"xxx","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.solar_forecast","state_type":"num","blockInputOverrides":false,"outputProperties":[{"property":"payload","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":400,"y":700,"wires":[["9953188c75662c5d","31849a963f6f7b09"]]},{"id":"31849a963f6f7b09","type":"debug","z":"3ab217fef43e55c3","name":"Solar Watt heute!","active":false,"tosidebar":true,"console":true,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":650,"y":640,"wires":[]},{"id":"7a9543ec2e74db50","type":"comment","z":"3ab217fef43e55c3","name":"Ziel SOC Ladezustand der Kellerbatterie festlegen, dass noch Sonne am nächsten Tag rein passt","info":"","x":370,"y":540,"wires":[]},{"id":"3480338b3a7c8163","type":"function","z":"3ab217fef43e55c3","name":"Transform Solar Forecast","func":"let solarForecast = msg.payload.result;\n\nif (!solarForecast) {\n return null;\n}\n\nlet dates = Object.keys(solarForecast);\nlet currentDate = dates[0]; // Annahme: Das Datum ist im ersten Eintrag\n\nmsg.payload = {\n state: solarForecast[currentDate],\n attributes: {\n watt_hours_day: solarForecast[currentDate],\n },\n solarForecast: solarForecast\n};\n\nreturn msg;\n","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":580,"wires":[["1f6c43ef8620444c"]]},{"id":"1f6c43ef8620444c","type":"ha-sensor","z":"3ab217fef43e55c3","name":"Solar_forecast","entityConfig":"06590ccc210681e7","version":0,"state":"payload","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":380,"y":640,"wires":[[]]},{"id":"91c912e197d3ff33","type":"subflow:93f485839dfa27a8","z":"3ab217fef43e55c3","name":"Solar forecast each day","env":[{"name":"latitude","value":"","type":"num"},{"name":"longitude","value":"","type":"num"},{"name":"declination","value":"0","type":"num"},{"name":"azimuth","value":"-8","type":"num"},{"name":"modules power","value":"8","type":"num"},{"name":"apikey","type":"cred"},{"name":"watt","value":"watthours/day","type":"str"},{"name":"kwhoutput","type":"bool","value":"true"},{"name":"daystoforecast","value":"1","type":"str"},{"name":"widengraph","type":"bool","value":"false"}],"x":190,"y":580,"wires":[["3480338b3a7c8163"],[]]},{"id":"8205f0764a5bc7ec","type":"inject","z":"3ab217fef43e55c3","name":"Test","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":740,"wires":[["e0a87f2cad0f9668"]]},{"id":"970baa16b90b95b3","type":"function","z":"3ab217fef43e55c3","name":"TibberPriceReceiver save global","func":"// Eingehender Payload mit dem Array\nvar newArrayTibberPrice = msg.payload && msg.payload.priceData ? msg.payload.priceData : [];\n\n// Überprüfen, ob newArrayTibberPrice vorhanden ist\nif (newArrayTibberPrice.length > 0) {\n // Überschreiben Sie die globale Variable mit dem neuen Array\n global.set(\"TibberPriceReceiver\", newArrayTibberPrice);\n };\n\n// Senden Sie den gespeicherten Array für den nächsten Node weiter (optional)\nmsg.payload = {\n priceData: global.get(\"TibberPriceReceiver\"),\n source: \"Tibber\"\n}\nreturn msg;\n\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":460,"wires":[["75ad5df12539cb35"]]},{"id":"4964d115f18a1ce2","type":"inject","z":"3ab217fef43e55c3","name":"TibberPlanung 30Min Update","props":[],"repeat":"1800","crontab":"","once":false,"onceDelay":"1","topic":"","x":210,"y":460,"wires":[["970baa16b90b95b3"]]},{"id":"2372f3bc28e08105","type":"ps-receive-price","z":"3ab217fef43e55c3","name":"Price Receiver","x":170,"y":260,"wires":[["970baa16b90b95b3","75ad5df12539cb35"]]},{"id":"d3a3164aafca26cd","type":"tibber-query","z":"3ab217fef43e55c3","name":"Get Tibber prices","active":true,"apiEndpointRef":"f037801398711328","x":540,"y":200,"wires":[["2372f3bc28e08105"]]},{"id":"1150af7f1b5365ad","type":"template","z":"3ab217fef43e55c3","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\n viewer {\n homes {\n currentSubscription {\n priceInfo {\n today {\n total\n startsAt\n }\n tomorrow {\n total\n startsAt\n }\n }\n }\n }\n }\n}","output":"str","x":350,"y":200,"wires":[["d3a3164aafca26cd"]]},{"id":"404bc41fbaaea7d9","type":"inject","z":"3ab217fef43e55c3","name":"TibberTagesPreise 14:00 Uhr ","props":[{"p":"payload"}],"repeat":"","crontab":"00 14 * * *","once":false,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":220,"y":140,"wires":[["1150af7f1b5365ad"]]},{"id":"8430cf1440405a3f","type":"comment","z":"3ab217fef43e55c3","name":"Dynamischen Strompreis von Tibber abrufen","info":"","x":230,"y":60,"wires":[]},{"id":"536cc4c3290d1e64","type":"ha-entity-config","server":"xxx","deviceConfig":"e2633874c3cb7f08","name":"sensor.powersaver_planning_akku_pv","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"sensor.powersaver_planning_akku_pv"},{"property":"icon","value":""},{"property":"entity_picture","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""}],"resend":false,"debugEnabled":false},{"id":"xxx","type":"server","name":"Home Assistant User","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false,"cacheJson":false,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":": ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"default","statusTimeFormat":"h:m","enableGlobalContextStore":false},{"id":"80a6d0d9529392b1","type":"ha-entity-config","server":"xxx","deviceConfig":"e17b1733ee1c1961","name":"pv-akku-vom-netz-bedingungen","version":"6","entityType":"binary_sensor","haConfig":[{"property":"name","value":"pv-akku-vom-netz-bedingungen"},{"property":"icon","value":""},{"property":"entity_picture","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":""}],"resend":false,"debugEnabled":false},{"id":"06590ccc210681e7","type":"ha-entity-config","server":"xxx","deviceConfig":"b7a6739f96f8e5eb","name":"Solar_forecast","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"Solar_forecast"},{"property":"icon","value":""},{"property":"entity_picture","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":"power"},{"property":"unit_of_measurement","value":"W"},{"property":"state_class","value":"total"}],"resend":false,"debugEnabled":false},{"id":"f037801398711328","type":"tibber-api-endpoint","queryUrl":"https://api.tibber.com/v1-beta/gql","feedConnectionTimeout":"30","feedTimeout":"60","queryRequestTimeout":"30","name":"Demo"},{"id":"e2633874c3cb7f08","type":"ha-device-config","name":"sensor.powersaver_planning_akku_pv","hwVersion":"","manufacturer":"Node-RED","model":"","swVersion":""},{"id":"e17b1733ee1c1961","type":"ha-device-config","name":"pv-akku-vom-netz-bedingungen","hwVersion":"","manufacturer":"Node-RED","model":"","swVersion":""},{"id":"b7a6739f96f8e5eb","type":"ha-device-config","name":"Solar_forecast","hwVersion":"","manufacturer":"Node-RED","model":"","swVersion":""}]