NEWS
Wie kann ich Zwei Analogwerte vergleichen.
-
Ich versuche Zwei Analogwerte zu vergleichen und eine Ausgang zu setzen, wie geht das.
[ { "id": "11059b537c80fb33", "type": "tab", "label": "Flow 2", "disabled": false, "info": "", "env": [] }, { "id": "bcdb24e1da584220", "type": "Comparator", "z": "11059b537c80fb33", "name": "Comparator", "property": "payload", "math": ">=", "topic1": "alpha-ess.0.Realtime.Battery_SOC", "topic2": "???", "x": 750, "y": 320, "wires": [ [ "e3bc9953db368ee5" ] ] }, { "id": "e3bc9953db368ee5", "type": "StatusUltimate", "z": "11059b537c80fb33", "name": "Ausgang", "property": "payload", "x": 940, "y": 320, "wires": [ [] ] }, { "id": "5172b14316cef3e5", "type": "ioBroker in", "z": "11059b537c80fb33", "name": "", "attrname": "payload", "topic": "alpha-ess.0.Realtime.Battery_SOC", "payloadType": "value", "onlyack": "", "func": "all", "gap": "", "fireOnStart": "false", "outFormat": "MQTT", "x": 280, "y": 260, "wires": [ [ "bcdb24e1da584220" ] ] }, { "id": "a0a95ab389b49c0f", "type": "change", "z": "11059b537c80fb33", "name": "zweiter Wert", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": " 90", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 410, "y": 360, "wires": [ [ "bcdb24e1da584220" ] ] }, { "id": "a7f2b0a13a124068", "type": "inject", "z": "11059b537c80fb33", "name": "", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 200, "y": 360, "wires": [ [ "a0a95ab389b49c0f" ] ] } ]
MOD-EDIT: Code in code-tags gesetzt!
-
@armin-2 und was genau willst du jetzt wissen?
https://forum.iobroker.net/topic/51555/hinweise-für-gute-forenbeiträge/1 -
@armin-2 um 2 Werte zu vergleichen musst du diese in ein Nachrichtenobjekt aufnehmen
und keine komischen Nodes verwenden
sondern lieber Standard Nodes
-
@mickym
Und wie geht das, kannst du meinen flow vielleicht mal anpassen?? -
@armin-2 Na ja aus Deinem Flow kann man nicht sehr viel entnehmen. Der 2. Werte ist ja auch noch ein String und 90 mit dem Du das vergleichst. Ausserdem schreibst Du überhaupt nichts was triggern soll und wiw gesagt - diese Nodes zum Vergleichen werde ich sicher nicht installieren.
Also wenn Du 2 Zahlen vergleichen willst musst Du auch bitte Zahlen nicht mit Strings vergleichen sondern auch mit einer Zahl
Also Datentyp beachten.
Du hast grundsätzlich mehrere Möglichkeiten Werte zu vergleichen. Da ich von Dir weder was triggered noch den Hintergrund erfahre überlege ich mir selbst einfach mal Szenarien.
- Möglichkeit - arbeiten über den Kontext.
Nehmen wir einmal an Du möchtest mehrere Werte mit einem dynamisch festgelegten Schwellenwert laufen lassen.
Die beiden Werte von fiktiven Temperatursensoren (sensor1 und sensor2) sollen also mit einem Schwellenwert aus dem Datenpunkt Wert verglichen werden. Für sowas bietet sich der Kontext an, da sich der Schwellenwert ja nicht so häufig ändert (man muss den aber ggf. initialisieren) also in jedem Fall Fire on Start in der iobroker-In auswählen.
Legen wir also mal fest, dass bei >= 25 °C der Flow verzweigt werden soll.
Wir lesen also den Schwellenwert sofort aus, wenn der Flow gestartet ist:
Diesen Schwellenwert speichern wir im Flow Kontext:
Wenn nun einer der fiktivien Temperatursensoren triggert, dann vergleichen wir diese Temperatur mit dem Schwellenwert - sagen wir mal >=25 und <25
Die beiden werden also nicht gegeneinander sondern gegen den Schwellenwert also einer 3. Zahl verglichen, die aber ebenfalls dynamisch aus den Objekten genutzt werden.
Man sieht also jeder Sensorwert wird mit dem Schwellenwert im Kontext verglichen und dann an den entsprechenden Ausgang geschickt.
- Die nächste Möglichkeit ist, dass die beiden Datenpunkte unabhängig von einander triggern lässt und sofort den 2. zu vergleichenden Wert holt.
Wir vergleichen also wieder Temperatur1 mit Temperatur2 und wollen sofort das Ergebnis haben.
Wir müssen also immer den 2. Wert aktiv holen, das macht man mit einer iobroker-get Node.
Damit das besser unterscheiden kann, werden wir die payload der Nachrichteneigenschaft der iobroker-In Node gleich in unterschiedliche Nachrichteneigenschaften gepackt.Wir packen also sowohl in der iobroker-IN-Node als auch in der iobroker-GET Node - die Werte in die Nachrichteneigenschaft temp1 und temp2
Hier mal die iobroker-In des 1. fiktivien Sensors als temp1.
In der nachfolgenden Get Node holen wir uns den 2. Wert in das gleiche Nachrichtenobjekt:
Schaut man sich also den Status an, so wird in das gleiche Nachrichtenobjekt der jeweils andere Wert geholt.
In einer switch Node kann ich nun wieder diese beiden Nachrichteneigenschaften des Nachrichtenobjektes vergleichen.
Ist also temp1 größer gleich temp2 wird an den 1. Ausgang geschickt, ist temp1 kleiner als temp2 an den 2. Ausgang geschickt.
- Die letzte Möglichkeit ist immer zu warten bis beide Werte einmal trigger - kann man ja auch gleich zu Beginn machen und diese in einer JOIN Node sammeln.
Wir lesen also die Werte gleich von Beginn an aus und dann lässt man sie triggern. In diesem Fall können wir beides Mal die Werte in die payload schreiben lassen:
Man sammelt nun beide Werte in einer JOIN Node - wartet bis wirklich beide Werte angekommen sind und vergleicht dann mit jeder neuen Nachricht.
Wichtig ist also dass wir dieses Mal ein Objekt als payload erstellen lassen und das topic als Nachrichteneigenschaft verwenden und dann auch noch 2 Nachrichten abwarten (also damit von jedem Sensor eine Nachricht vorhanden ist).
Aufgrund der Zusammenfassung in der JOIN Node - haben wir beide Werte nun nicht nur in einem Nachrichtenobjekt sondern auch zusammen in einer payload
die kann ich nun wieder vergleichen.
Der Vergleich in der switch Node erfolgt also auf die gleiche Weise wie unter Möglichkeit 2 nur dass in diesem Fall 2 Eigenschaften des payload OBJEKTES verglichen werden.
In diesem Fall muss die payload Eigenschaft in Hochkomma gesetzt werden, da die Eigenschaften Sonderzeichen enthält.
Es empfiehlt sich also das topic vor der Change Node noch zu kürzen.Der Vergleich fällt aber identisch aus.
FAZIT:
Ich habe Dir nun alle 3 Möglichkeiten im Detail beschrieben und hier aufgelistet:
Hier nun alle Flows zum Import und zur eigenen Verwendung.
-
Danke für die Mühe, aber das passt so noch nicht.
Hier nochmal mein Problem.
Ich möchte einen Wert von IO-Broker mit einem Wert "change" vergleichen und ein Bit z.B. im IOBroker setzen.
[
{
"id": "32ca1d3d3965fa09",
"type": "tab",
"label": "Flow 2",
"disabled": false,
"info": "",
"env": []
},
{
"id": "1a1283bbbd4c8410",
"type": "ioBroker out",
"z": "32ca1d3d3965fa09",
"name": "Battery Charging enabled [gridCharge]",
"topic": "alpha-ess.0.Settings_Charge.Battery_Charging_enabled",
"ack": "false",
"autoCreate": "false",
"stateName": "",
"role": "",
"payloadType": "",
"readonly": "",
"stateUnit": "",
"stateMin": "",
"stateMax": "",
"x": 1050,
"y": 340,
"wires": []
},
{
"id": "a2d7ca6eafbe6e71",
"type": "ioBroker in",
"z": "32ca1d3d3965fa09",
"name": " alpha-ess.0.Realtime.Battery_SOC",
"attrname": "temp1",
"topic": "alpha-ess.0.Realtime.Battery_SOC",
"payloadType": "value",
"onlyack": "",
"func": "all",
"gap": "",
"fireOnStart": "false",
"outFormat": "MQTT",
"x": 300,
"y": 260,
"wires": [
[]
]
},
{
"id": "92f11862fdebb1a9",
"type": "change",
"z": "32ca1d3d3965fa09",
"name": "SOC 20",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "20",
"tot": "num"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 380,
"y": 340,
"wires": [
[]
]
},
{
"id": "82df9544976c9930",
"type": "inject",
"z": "32ca1d3d3965fa09",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 160,
"y": 340,
"wires": [
[
"92f11862fdebb1a9"
]
]
},
{
"id": "ba6a0a91683436e9",
"type": "switch",
"z": "32ca1d3d3965fa09",
"name": "",
"property": "temp1 >= temp2",
"propertyType": "jsonata",
"rules": [
{
"t": "true"
},
{
"t": "false"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 750,
"y": 340,
"wires": [
[
"1a1283bbbd4c8410",
"33fca06d3914b1cb"
],
[]
]
},
{
"id": "33fca06d3914b1cb",
"type": "debug",
"z": "32ca1d3d3965fa09",
"name": "Charging Einschalten",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1000,
"y": 260,
"wires": []
}
] -
So korrigiert - siehe nächster Post.
-
@mickym
Ich möchte einen Wert von IO-Broker mit einem Wert aus "change" vergleichen, der aus einem andern Flow kommt und ein Bit z.B. im IOBroker setzen, wenn der Wert aus dem IOBroker >= dem Wert aus dem "change" ist. -
Mach das mit dem Kontext. Der zweite Wert wird über die Change Node im Flow Kontext gespeichert.
Wird Batterie_SOC getriggert wird der Kontext wieder in das Nachrichtenobjekt in die Eigenschaft value geladen.
Hier zum Import:
Bzw. (s. nächster Post) aus dem anderen Flow den Wert direkt im globalen Kontext speichern.
-
@armin-2 Du kannst es auch aus dem anderen Flow - im globalen Kontext speichern!!! So würde ich es machen. Aber ich kenne ja den anderen Flow nicht.
In dem anderen Flow speicherst Du im globalen Kontext
Dann kannst Du den globalen Kontext in der Change Node wieder aus der Variablen einlesen:
Dann brauchst Du die Flows NICHT zu verlinken, sondern tauscht über den globalen Kontext aus.
-
Das passt immer noch nicht. Hier mein ganzer Flow mit Beschreibung, vielleicht hilft das.
[
{
"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 onlyestimate
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
- historical data showing the long term averages for the days to come. See https://joint-research-centre.ec.europa.eu/pvgis-online-tool/pvgis-data-download/cm-saf-solar-radiation_en for where the data is fetched from.\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-watt_hours_period
- Watt hours (energy) for the period\n-watt_hours
- Watt hours (energy) summarized over the day\n-watt_hours_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\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 themsg.payload
.\n\nMost important is themsg.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\nThemsg.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 ofremaining/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",
"type": "input",
"opts": {
"types": [
"num"
]
}
}
},
{
"name": "longitude",
"type": "num",
"value": "5.6",
"ui": {
"icon": "font-awesome/fa-location-arrow",
"type": "input",
"opts": {
"types": [
"num"
]
}
}
},
{
"name": "declination",
"type": "num",
"value": "37",
"ui": {
"icon": "font-awesome/fa-chevron-up",
"type": "input",
"opts": {
"types": [
"num"
]
}
}
},
{
"name": "azimuth",
"type": "num",
"value": "0",
"ui": {
"icon": "font-awesome/fa-compass",
"type": "spinner",
"opts": {
"min": -180,
"max": 180
}
}
},
{
"name": "modules power",
"type": "num",
"value": "1",
"ui": {
"icon": "font-awesome/fa-power-off",
"type": "input",
"opts": {
"types": [
"num"
]
}
}
},
{
"name": "apikey",
"type": "cred",
"ui": {
"icon": "font-awesome/fa-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",
"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": "watt_hours_period"
},
{
"l": {
"en-US": "Watt hours (energy) summarized over the day"
},
"v": "watt_hours"
},
{
"l": {
"en-US": "Watt hours (energy) summarized for each day"
},
"v": "watt_hours_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"
}
}
],
"meta": {
"module": "Solar Forecast",
"version": "0.0.9",
"author": "dfaber@victronenergy.com",
"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": "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 m.series.push("Watt hours per day");\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][hmsg.resolution+offset] = +(Math.round(msg.payload.result[key]/100).1).toFixed(1);\n } else {\n m.data[m.series.length - 1][hmsg.resolution+offset] = msg.payload.result[key];\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",
> 0) {\n remove = false;\n }\n }\n if (remove) {\n msg.payload[0].labels.splice(x, 1);\n for (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 (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": "c8dc6aa14b9f3e92",
"type": "delay",
"z": "93f485839dfa27a8",
"name": "5 msg/15 minutes",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "5",
"nbRateUnits": "15",
"rateUnits": "minute",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 390,
"y": 100,
"wires": [
[
"b9488734852cd0ca"
]
]
},
{
"id": "32ca1d3d3965fa09",
"type": "tab",
"label": "Flow 2",
"disabled": false,
"info": "",
"env": []
},
{
"id": "93511f47e1f57f02",
"type": "group",
"z": "32ca1d3d3965fa09",
"name": "Sammeln der Daten in JOIN Node",
"style": {
"fill": "#d1d1d1",
"label": true,
"color": "#000000"
},
"nodes": [
"9aecc09bd88aa42a",
"5dc336ee1d2a02da",
"008ab1d49e4bb116"
],
"x": 154,
"y": 99,
"w": 672,
"h": 82
},
{
"id": "47a4cf54866c5a93",
"type": "inject",
"z": "32ca1d3d3965fa09",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 120,
"y": 460,
"wires": [
[
"206c8fbe5daa2c1e"
]
]
},
{
"id": "206c8fbe5daa2c1e",
"type": "subflow:93f485839dfa27a8",
"z": "32ca1d3d3965fa09",
"name": "Süd",
"env": [
{
"name": "latitude",
"value": "51.0618535",
"type": "num"
},
{
"name": "longitude",
"value": "7.376629",
"type": "num"
},
{
"name": "declination",
"value": "40",
"type": "num"
},
{
"name": "azimuth",
"value": "182",
"type": "num"
},
{
"name": "modules power",
"value": "9",
"type": "num"
},
{
"name": "apikey",
"type": "cred"
},
{
"name": "watt",
"value": "watt_hours_day",
"type": "str"
},
{
"name": "showtoday",
"type": "bool",
"value": "false"
},
{
"name": "daystoforecast",
"value": "1",
"type": "str"
},
{
"name": "widengraph",
"type": "bool",
"value": "false"
}
],
"x": 310,
"y": 460,
"wires": [
[
"57dc8d4b5bbeaa7f"
],
[]
]
},
{
"id": "57dc8d4b5bbeaa7f",
"type": "function",
"z": "32ca1d3d3965fa09",
"name": "function 16",
"func": "var pvf = msg.payload;\nvar date = moment().tz("Europe/Berlin");\nvar today = date.format('YYYY-MM-DD');\nvar hourEntries = Object.keys(pvf.result);\nvar todaysEntries = hourEntries.filter(x => x.startsWith(today));\nvar expectedEarning = pvf.result[todaysEntries[todaysEntries.length -1]];\nmsg.payload = expectedEarning;\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [
{
"var": "moment",
"module": "moment"
}
],
"x": 530,
"y": 460,
"wires": [
[
"15b38fae77d09de8"
]
]
},
{
"id": "15b38fae77d09de8",
"type": "switch",
"z": "32ca1d3d3965fa09",
"name": "",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "lt",
"v": "2000",
"vt": "str"
},
{
"t": "btwn",
"v": "2000",
"vt": "num",
"v2": "5000",
"v2t": "num"
},
{
"t": "btwn",
"v": "5000",
"vt": "num",
"v2": "8000",
"v2t": "num"
},
{
"t": "gt",
"v": "8000",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 4,
"x": 690,
"y": 460,
"wires": [
[
"d05020b1296929fc"
],
[
"6109976a13173762"
],
[
"7b0b92dc28fd1808"
],
[
"0aaf3b0d4e58724e"
]
]
},
{
"id": "d05020b1296929fc",
"type": "change",
"z": "32ca1d3d3965fa09",
"name": "SOC 100",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "100",
"tot": "num"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 860,
"y": 400,
"wires": [
[
"236747505d6180f7",
"5f11d27a7408ff35",
"5dc336ee1d2a02da"
]
]
},
{
"id": "6109976a13173762",
"type": "change",
"z": "32ca1d3d3965fa09",
"name": "SOC 60",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "60",
"tot": "num"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 860,
"y": 440,
"wires": [
[
"236747505d6180f7",
"5f11d27a7408ff35",
"5dc336ee1d2a02da"
]
]
},
{
"id": "7b0b92dc28fd1808",
"type": "change",
"z": "32ca1d3d3965fa09",
"name": "SOC 40",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "40",
"tot": "num"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 860,
"y": 480,
"wires": [
[
"236747505d6180f7",
"5f11d27a7408ff35",
"5dc336ee1d2a02da"
]
]
},
{
"id": "0aaf3b0d4e58724e",
"type": "change",
"z": "32ca1d3d3965fa09",
"name": "SOC 20",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "20",
"tot": "num"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 860,
"y": 520,
"wires": [
[
"236747505d6180f7",
"5f11d27a7408ff35",
"5dc336ee1d2a02da"
]
]
},
{
"id": "9aecc09bd88aa42a",
"type": "ioBroker in",
"z": "32ca1d3d3965fa09",
"g": "93511f47e1f57f02",
"name": "temperature von sensor1",
"attrname": "payload",
"topic": "0_userdata.0.Test.sensor1.temperature",
"payloadType": "value",
"onlyack": "",
"func": "all",
"gap": "",
"fireOnStart": "true",
"outFormat": "MQTT",
"x": 290,
"y": 140,
"wires": [
[
"5dc336ee1d2a02da"
]
]
},
{
"id": "5dc336ee1d2a02da",
"type": "join",
"z": "32ca1d3d3965fa09",
"g": "93511f47e1f57f02",
"name": "",
"mode": "custom",
"build": "object",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\n",
"joinerType": "str",
"accumulate": true,
"timeout": "",
"count": "2",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 590,
"y": 140,
"wires": [
[
"008ab1d49e4bb116"
]
]
},
{
"id": "008ab1d49e4bb116",
"type": "switch",
"z": "32ca1d3d3965fa09",
"g": "93511f47e1f57f02",
"name": "",
"property": "payload.'0_userdata/0/Test/sensor1/temperature' >= payload.'0_userdata/0/Test/sensor2/temperature'",
"propertyType": "jsonata",
"rules": [
{
"t": "true"
},
{
"t": "false"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 750,
"y": 140,
"wires": [
[
"b4c362324a598e06",
"0e44e66f0eb20551"
],
[]
]
},
{
"id": "32a2eb3db62922d1",
"type": "comment",
"z": "32ca1d3d3965fa09",
"name": "solar forecast lesen",
"info": "",
"x": 330,
"y": 400,
"wires": []
},
{
"id": "f8f09c0fbe1d0129",
"type": "comment",
"z": "32ca1d3d3965fa09",
"name": "daten für den Tag aufbereiten",
"info": "",
"x": 540,
"y": 400,
"wires": []
},
{
"id": "2560460ee7ece326",
"type": "comment",
"z": "32ca1d3d3965fa09",
"name": "Daten jede Stunde lesen",
"info": "",
"x": 130,
"y": 400,
"wires": []
},
{
"id": "92f7dcf1abe763bc",
"type": "comment",
"z": "32ca1d3d3965fa09",
"name": "je nach Leistung SOC für Batterie festlegen",
"info": "",
"x": 820,
"y": 580,
"wires": []
},
{
"id": "236747505d6180f7",
"type": "ioBroker out",
"z": "32ca1d3d3965fa09",
"name": "Discharging Cutoff SOC [batUseCap]",
"topic": "alpha-ess.0.Settings_Discharge.Discharging_Cutoff_SOC",
"ack": "false",
"autoCreate": "false",
"stateName": "",
"role": "",
"payloadType": "",
"readonly": "",
"stateUnit": "",
"stateMin": "",
"stateMax": "",
"x": 1170,
"y": 400,
"wires": []
},
{
"id": "5f11d27a7408ff35",
"type": "ioBroker get",
"z": "32ca1d3d3965fa09",
"name": "Discharging Cutoff SOC [batUseCap]",
"topic": "alpha-ess.0.Settings_Discharge.Discharging_Cutoff_SOC",
"attrname": "payload",
"payloadType": "object",
"errOnInvalidState": "nothing",
"x": 1170,
"y": 480,
"wires": [
[]
]
},
{
"id": "4036c9e7d228d42d",
"type": "comment",
"z": "32ca1d3d3965fa09",
"name": "Wert an IOBroker geben",
"info": "",
"x": 1150,
"y": 580,
"wires": []
},
{
"id": "280378479ef948d1",
"type": "comment",
"z": "32ca1d3d3965fa09",
"name": "vergleichen ob Batterieladung größe als berechneter Wert Ist",
"info": "",
"x": 640,
"y": 220,
"wires": []
},
{
"id": "55de461857057e67",
"type": "comment",
"z": "32ca1d3d3965fa09",
"name": "SOC Wert von Batterie",
"info": "",
"x": 280,
"y": 220,
"wires": []
},
{
"id": "b4c362324a598e06",
"type": "ioBroker out",
"z": "32ca1d3d3965fa09",
"name": "Battery Charging enabled [gridCharge]",
"topic": "alpha-ess.0.Settings_Charge.Battery_Charging_enabled",
"ack": "false",
"autoCreate": "false",
"stateName": "",
"role": "",
"payloadType": "",
"readonly": "",
"stateUnit": "",
"stateMin": "",
"stateMax": "",
"x": 1110,
"y": 60,
"wires": []
},
{
"id": "0e44e66f0eb20551",
"type": "ioBroker get",
"z": "32ca1d3d3965fa09",
"name": "Battery Charging enabled [gridCharge]",
"topic": "alpha-ess.0.Settings_Charge.Battery_Charging_enabled",
"attrname": "payload",
"payloadType": "object",
"errOnInvalidState": "nothing",
"x": 1110,
"y": 120,
"wires": [
[]
]
},
{
"id": "199bac5fd12314a5",
"type": "comment",
"z": "32ca1d3d3965fa09",
"name": "Batterie laden EIN/Aus",
"info": "",
"x": 1060,
"y": 220,
"wires": []
}
] -
Ja ich könnte mir das Anschauen, wenn Du Deinen Flow in ein Code-Tags packst - sowas ist nutzlos !!!
-
Ist das so Richtig?
[ { "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` - historical data showing the long term averages for the days to come. See [https://joint-research-centre.ec.europa.eu/pvgis-online-tool/pvgis-data-download/cm-saf-solar-radiation_en](https://joint-research-centre.ec.europa.eu/pvgis-online-tool/pvgis-data-download/cm-saf-solar-radiation_en) for where the data is fetched from.\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- `watt_hours_period` - Watt hours (energy) for the period\n- `watt_hours` - Watt hours (energy) summarized over the day\n- `watt_hours_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\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", "type": "input", "opts": { "types": [ "num" ] } } }, { "name": "longitude", "type": "num", "value": "5.6", "ui": { "icon": "font-awesome/fa-location-arrow", "type": "input", "opts": { "types": [ "num" ] } } }, { "name": "declination", "type": "num", "value": "37", "ui": { "icon": "font-awesome/fa-chevron-up", "type": "input", "opts": { "types": [ "num" ] } } }, { "name": "azimuth", "type": "num", "value": "0", "ui": { "icon": "font-awesome/fa-compass", "type": "spinner", "opts": { "min": -180, "max": 180 } } }, { "name": "modules power", "type": "num", "value": "1", "ui": { "icon": "font-awesome/fa-power-off", "type": "input", "opts": { "types": [ "num" ] } } }, { "name": "apikey", "type": "cred", "ui": { "icon": "font-awesome/fa-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", "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": "watt_hours_period" }, { "l": { "en-US": "Watt hours (energy) summarized over the day" }, "v": "watt_hours" }, { "l": { "en-US": "Watt hours (energy) summarized for each day" }, "v": "watt_hours_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" } } ], "meta": { "module": "Solar Forecast", "version": "0.0.9", "author": "dfaber@victronenergy.com", "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": "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 m.series.push(\"Watt hours per day\");\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\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 ((env.get('daystoforecast') > -1) && (env.get('daystoforecast') < forecasted)) {\n for (i = 1; i < (forecasted - env.get('daystoforecast')); i++ ) {\n msg.payload[0].data.pop();\n msg.payload[0].series.pop();\n }\n}\n\nif (env.get('watt') === 'watt_hours_day' ) {\n forecasted = msg.payload[0].labels.length;\n for (i = 1; i < (forecasted - env.get('daystoforecast')); i++ ) {\n msg.payload[0].labels.pop();\n msg.payload[0].data[0].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('widengraph')) {\n var c = msg.payload[0].labels.length;\n var x = 0;\n for (i = 0; i < c; i++) {\n var remove = true;\n for (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 (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 (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": "c8dc6aa14b9f3e92", "type": "delay", "z": "93f485839dfa27a8", "name": "5 msg/15 minutes", "pauseType": "rate", "timeout": "5", "timeoutUnits": "seconds", "rate": "5", "nbRateUnits": "15", "rateUnits": "minute", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 390, "y": 100, "wires": [ [ "b9488734852cd0ca" ] ] }, { "id": "32ca1d3d3965fa09", "type": "tab", "label": "an foren", "disabled": false, "info": "", "env": [] }, { "id": "93511f47e1f57f02", "type": "group", "z": "32ca1d3d3965fa09", "name": "Sammeln der Daten in JOIN Node", "style": { "fill": "#d1d1d1", "label": true, "color": "#000000" }, "nodes": [ "9aecc09bd88aa42a", "5dc336ee1d2a02da", "008ab1d49e4bb116" ], "x": 154, "y": 99, "w": 672, "h": 82 }, { "id": "47a4cf54866c5a93", "type": "inject", "z": "32ca1d3d3965fa09", "name": "", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 120, "y": 460, "wires": [ [ "206c8fbe5daa2c1e" ] ] }, { "id": "206c8fbe5daa2c1e", "type": "subflow:93f485839dfa27a8", "z": "32ca1d3d3965fa09", "name": "Süd", "env": [ { "name": "latitude", "value": "51.0618535", "type": "num" }, { "name": "longitude", "value": "7.376629", "type": "num" }, { "name": "declination", "value": "40", "type": "num" }, { "name": "azimuth", "value": "182", "type": "num" }, { "name": "modules power", "value": "9", "type": "num" }, { "name": "apikey", "type": "cred" }, { "name": "watt", "value": "watt_hours_day", "type": "str" }, { "name": "showtoday", "type": "bool", "value": "false" }, { "name": "daystoforecast", "value": "1", "type": "str" }, { "name": "widengraph", "type": "bool", "value": "false" } ], "x": 310, "y": 460, "wires": [ [ "57dc8d4b5bbeaa7f" ], [] ] }, { "id": "57dc8d4b5bbeaa7f", "type": "function", "z": "32ca1d3d3965fa09", "name": "function 16", "func": "var pvf = msg.payload;\nvar date = moment().tz(\"Europe/Berlin\");\nvar today = date.format('YYYY-MM-DD');\nvar hourEntries = Object.keys(pvf.result);\nvar todaysEntries = hourEntries.filter(x => x.startsWith(today));\nvar expectedEarning = pvf.result[todaysEntries[todaysEntries.length -1]];\nmsg.payload = expectedEarning;\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [ { "var": "moment", "module": "moment" } ], "x": 530, "y": 460, "wires": [ [ "15b38fae77d09de8" ] ] }, { "id": "15b38fae77d09de8", "type": "switch", "z": "32ca1d3d3965fa09", "name": "", "property": "payload", "propertyType": "msg", "rules": [ { "t": "lt", "v": "2000", "vt": "str" }, { "t": "btwn", "v": "2000", "vt": "num", "v2": "5000", "v2t": "num" }, { "t": "btwn", "v": "5000", "vt": "num", "v2": "8000", "v2t": "num" }, { "t": "gt", "v": "8000", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 4, "x": 690, "y": 460, "wires": [ [ "d05020b1296929fc" ], [ "6109976a13173762" ], [ "7b0b92dc28fd1808" ], [ "0aaf3b0d4e58724e" ] ] }, { "id": "d05020b1296929fc", "type": "change", "z": "32ca1d3d3965fa09", "name": "SOC 100", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "100", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 860, "y": 400, "wires": [ [ "236747505d6180f7", "5f11d27a7408ff35", "5dc336ee1d2a02da" ] ] }, { "id": "6109976a13173762", "type": "change", "z": "32ca1d3d3965fa09", "name": "SOC 60", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "60", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 860, "y": 440, "wires": [ [ "236747505d6180f7", "5f11d27a7408ff35", "5dc336ee1d2a02da" ] ] }, { "id": "7b0b92dc28fd1808", "type": "change", "z": "32ca1d3d3965fa09", "name": "SOC 40", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "40", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 860, "y": 480, "wires": [ [ "236747505d6180f7", "5f11d27a7408ff35", "5dc336ee1d2a02da" ] ] }, { "id": "0aaf3b0d4e58724e", "type": "change", "z": "32ca1d3d3965fa09", "name": "SOC 20", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "20", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 860, "y": 520, "wires": [ [ "236747505d6180f7", "5f11d27a7408ff35", "5dc336ee1d2a02da" ] ] }, { "id": "9aecc09bd88aa42a", "type": "ioBroker in", "z": "32ca1d3d3965fa09", "g": "93511f47e1f57f02", "name": "temperature von sensor1", "attrname": "payload", "topic": "0_userdata.0.Test.sensor1.temperature", "payloadType": "value", "onlyack": "", "func": "all", "gap": "", "fireOnStart": "true", "outFormat": "MQTT", "x": 290, "y": 140, "wires": [ [ "5dc336ee1d2a02da" ] ] }, { "id": "5dc336ee1d2a02da", "type": "join", "z": "32ca1d3d3965fa09", "g": "93511f47e1f57f02", "name": "", "mode": "custom", "build": "object", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": true, "timeout": "", "count": "2", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "", "reduceFixup": "", "x": 590, "y": 140, "wires": [ [ "008ab1d49e4bb116" ] ] }, { "id": "008ab1d49e4bb116", "type": "switch", "z": "32ca1d3d3965fa09", "g": "93511f47e1f57f02", "name": "", "property": "payload.'0_userdata/0/Test/sensor1/temperature' >= payload.'0_userdata/0/Test/sensor2/temperature'", "propertyType": "jsonata", "rules": [ { "t": "true" }, { "t": "false" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 750, "y": 140, "wires": [ [ "b4c362324a598e06", "0e44e66f0eb20551" ], [] ] }, { "id": "32a2eb3db62922d1", "type": "comment", "z": "32ca1d3d3965fa09", "name": "solar forecast lesen", "info": "", "x": 330, "y": 400, "wires": [] }, { "id": "f8f09c0fbe1d0129", "type": "comment", "z": "32ca1d3d3965fa09", "name": "daten für den Tag aufbereiten", "info": "", "x": 540, "y": 400, "wires": [] }, { "id": "2560460ee7ece326", "type": "comment", "z": "32ca1d3d3965fa09", "name": "Daten jede Stunde lesen", "info": "", "x": 130, "y": 400, "wires": [] }, { "id": "92f7dcf1abe763bc", "type": "comment", "z": "32ca1d3d3965fa09", "name": "je nach Leistung SOC für Batterie festlegen", "info": "", "x": 820, "y": 580, "wires": [] }, { "id": "236747505d6180f7", "type": "ioBroker out", "z": "32ca1d3d3965fa09", "name": "Discharging Cutoff SOC [batUseCap]", "topic": "alpha-ess.0.Settings_Discharge.Discharging_Cutoff_SOC", "ack": "false", "autoCreate": "false", "stateName": "", "role": "", "payloadType": "", "readonly": "", "stateUnit": "", "stateMin": "", "stateMax": "", "x": 1170, "y": 400, "wires": [] }, { "id": "5f11d27a7408ff35", "type": "ioBroker get", "z": "32ca1d3d3965fa09", "name": "Discharging Cutoff SOC [batUseCap]", "topic": "alpha-ess.0.Settings_Discharge.Discharging_Cutoff_SOC", "attrname": "payload", "payloadType": "object", "errOnInvalidState": "nothing", "x": 1170, "y": 480, "wires": [ [] ] }, { "id": "4036c9e7d228d42d", "type": "comment", "z": "32ca1d3d3965fa09", "name": "Wert an IOBroker geben", "info": "", "x": 1150, "y": 580, "wires": [] }, { "id": "280378479ef948d1", "type": "comment", "z": "32ca1d3d3965fa09", "name": "vergleichen ob Batterieladung größe als berechneter Wert Ist", "info": "", "x": 640, "y": 220, "wires": [] }, { "id": "55de461857057e67", "type": "comment", "z": "32ca1d3d3965fa09", "name": "SOC Wert von Batterie", "info": "", "x": 280, "y": 220, "wires": [] }, { "id": "b4c362324a598e06", "type": "ioBroker out", "z": "32ca1d3d3965fa09", "name": "Battery Charging enabled [gridCharge]", "topic": "alpha-ess.0.Settings_Charge.Battery_Charging_enabled", "ack": "false", "autoCreate": "false", "stateName": "", "role": "", "payloadType": "", "readonly": "", "stateUnit": "", "stateMin": "", "stateMax": "", "x": 1110, "y": 60, "wires": [] }, { "id": "0e44e66f0eb20551", "type": "ioBroker get", "z": "32ca1d3d3965fa09", "name": "Battery Charging enabled [gridCharge]", "topic": "alpha-ess.0.Settings_Charge.Battery_Charging_enabled", "attrname": "payload", "payloadType": "object", "errOnInvalidState": "nothing", "x": 1110, "y": 120, "wires": [ [] ] }, { "id": "199bac5fd12314a5", "type": "comment", "z": "32ca1d3d3965fa09", "name": "Batterie laden EIN/Aus", "info": "", "x": 1060, "y": 220, "wires": [] } ]
-
Ja jetzt kann ich damit was anfangen.
-
So ich habs mal so geändert wie ich es für sinnvoll halte - was Deine getNodes da sollen weiß ich nicht. Du kannst die Debug node (check) bei Bedarf auch aktivieren, um die Werte zu sehen:
Hier zum Import:
Im Übrigen, WENN das so klappt - warum postest Du eigentlich nicht von Anfang an Deinen Flow und wir mühen uns ab, weil wir nicht wissen, was Du machen willst?
-
Vielen Dank , So klappt es.
Ich bin neue hier, und wusste nicht genau was Ihr braucht.
Bei der nächsten Frage klappt es hoffentlich besser.
Aber jetzt haben wir es ja.
Das zweite Schreiben an den IOBroker, ist zum Setzen des Bestätigung Bits auf true.
Sonst wird der Wert nicht verschickt.
Nochmal vielen Dank, wieder viel dazu gelernt.
Armin -
@armin-2
Hallo hier doch nochmal eine Frage, welcher Fehler ist in dem Teil Werte addieren, den ich dazwichen geschoben habe?
Ich habe drei verschiedene Solarausrichtungen.[ { "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` - historical data showing the long term averages for the days to come. See [https://joint-research-centre.ec.europa.eu/pvgis-online-tool/pvgis-data-download/cm-saf-solar-radiation_en](https://joint-research-centre.ec.europa.eu/pvgis-online-tool/pvgis-data-download/cm-saf-solar-radiation_en) for where the data is fetched from.\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- `watt_hours_period` - Watt hours (energy) for the period\n- `watt_hours` - Watt hours (energy) summarized over the day\n- `watt_hours_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\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", "type": "input", "opts": { "types": [ "num" ] } } }, { "name": "longitude", "type": "num", "value": "5.6", "ui": { "icon": "font-awesome/fa-location-arrow", "type": "input", "opts": { "types": [ "num" ] } } }, { "name": "declination", "type": "num", "value": "37", "ui": { "icon": "font-awesome/fa-chevron-up", "type": "input", "opts": { "types": [ "num" ] } } }, { "name": "azimuth", "type": "num", "value": "0", "ui": { "icon": "font-awesome/fa-compass", "type": "spinner", "opts": { "min": -180, "max": 180 } } }, { "name": "modules power", "type": "num", "value": "1", "ui": { "icon": "font-awesome/fa-power-off", "type": "input", "opts": { "types": [ "num" ] } } }, { "name": "apikey", "type": "cred", "ui": { "icon": "font-awesome/fa-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", "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": "watt_hours_period" }, { "l": { "en-US": "Watt hours (energy) summarized over the day" }, "v": "watt_hours" }, { "l": { "en-US": "Watt hours (energy) summarized for each day" }, "v": "watt_hours_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" } } ], "meta": { "module": "Solar Forecast", "version": "0.0.9", "author": "dfaber@victronenergy.com", "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": "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 m.series.push(\"Watt hours per day\");\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\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 ((env.get('daystoforecast') > -1) && (env.get('daystoforecast') < forecasted)) {\n for (i = 1; i < (forecasted - env.get('daystoforecast')); i++ ) {\n msg.payload[0].data.pop();\n msg.payload[0].series.pop();\n }\n}\n\nif (env.get('watt') === 'watt_hours_day' ) {\n forecasted = msg.payload[0].labels.length;\n for (i = 1; i < (forecasted - env.get('daystoforecast')); i++ ) {\n msg.payload[0].labels.pop();\n msg.payload[0].data[0].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('widengraph')) {\n var c = msg.payload[0].labels.length;\n var x = 0;\n for (i = 0; i < c; i++) {\n var remove = true;\n for (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 (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 (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": "c8dc6aa14b9f3e92", "type": "delay", "z": "93f485839dfa27a8", "name": "5 msg/15 minutes", "pauseType": "rate", "timeout": "5", "timeoutUnits": "seconds", "rate": "5", "nbRateUnits": "15", "rateUnits": "minute", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 390, "y": 100, "wires": [ [ "b9488734852cd0ca" ] ] }, { "id": "11da2ee7fe92bba9", "type": "tab", "label": "Batterie Laden", "disabled": false, "info": "", "env": [] }, { "id": "882f920692db15ac", "type": "group", "z": "11da2ee7fe92bba9", "name": "Batterie laden", "style": { "fill": "#d1d1d1", "label": true, "color": "#0070c0" }, "nodes": [ "d2960c5258a6aa87", "0e02a8c5b8713878", "a556e20d6775b89e", "eaa7a8710b8bd555", "5dd7f104e86726b9", "87926d98a6caa2b7", "86a568bb366b5a53", "4951b0f4623d4bba", "d9368294d9621a30", "6c3cb62857c3f0cc", "3ccafa7058527caf", "b99a5fcf56fa30db" ], "x": 14, "y": 39, "w": 1532, "h": 222 }, { "id": "8885f238d46c98d4", "type": "group", "z": "11da2ee7fe92bba9", "name": "Batterie SOC festlegen", "style": { "fill": "#d1d1d1", "label": true, "color": "#0070c0" }, "nodes": [ "cc1bdb4e806c49d3", "08f1fa9012a05ea5", "c4d7dd8d06fa28f9", "0e39db21507d2496", "db9a8c492c1eacbf", "af5c4e99e154bf35", "0d520e8869dda085", "162844c501bda2cb", "29adc486d67dc5b4", "70bc14a931ad4c71", "df70959a7049e70c", "0740f2f6d8be4dc3", "c0f098512f61f09e", "db2f79c5ba46ec03", "8cdb8e157b315411", "3d56edb712404a94", "7dcab65894d85d27", "805b9497e42fd964", "af50b69abaa6e3f2", "0217fa6ea639b794", "6def2e19d5482654", "a3feba0d2f7707c9", "1d46f7e375b6f7e2", "043c5238cb193231", "98639d190c555169", "bb6880f6962e941b" ], "x": 14, "y": 379, "w": 1532, "h": 302 }, { "id": "3d56edb712404a94", "type": "junction", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "x": 1140, "y": 480, "wires": [ [ "8cdb8e157b315411" ] ] }, { "id": "d2960c5258a6aa87", "type": "ioBroker in", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "SOC von Batterie", "attrname": "payload", "topic": "alpha-ess.0.Realtime.Battery_SOC", "payloadType": "value", "onlyack": "", "func": "all", "gap": "", "fireOnStart": "true", "outFormat": "MQTT", "x": 120, "y": 140, "wires": [ [ "4951b0f4623d4bba" ] ] }, { "id": "0e02a8c5b8713878", "type": "join", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "", "mode": "custom", "build": "object", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": true, "timeout": "", "count": "2", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "", "reduceFixup": "", "x": 490, "y": 140, "wires": [ [ "a556e20d6775b89e" ] ] }, { "id": "a556e20d6775b89e", "type": "switch", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "", "property": "payload", "propertyType": "msg", "rules": [ { "t": "jsonata_exp", "v": "payload.batterie < payload.soll", "vt": "jsonata" }, { "t": "jsonata_exp", "v": "payload.batterie >= payload.soll", "vt": "jsonata" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 630, "y": 140, "wires": [ [ "d9368294d9621a30" ], [ "6c3cb62857c3f0cc" ] ] }, { "id": "eaa7a8710b8bd555", "type": "comment", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "vergleichen ob Batterieladung größe als berechneter Wert Ist", "info": "", "x": 560, "y": 220, "wires": [] }, { "id": "5dd7f104e86726b9", "type": "comment", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "SOC Wert von Batterie", "info": "", "x": 200, "y": 220, "wires": [] }, { "id": "87926d98a6caa2b7", "type": "ioBroker out", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "Battery Charging enabled [gridCharge]", "topic": "alpha-ess.0.Settings_Charge.Battery_Charging_enabled", "ack": "false", "autoCreate": "false", "stateName": "", "role": "", "payloadType": "", "readonly": "", "stateUnit": "", "stateMin": "", "stateMax": "", "x": 1330, "y": 140, "wires": [] }, { "id": "86a568bb366b5a53", "type": "comment", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "Batterie laden EIN/Aus", "info": "", "x": 1020, "y": 220, "wires": [] }, { "id": "4951b0f4623d4bba", "type": "change", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "topic = batterie", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "batterie", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 320, "y": 140, "wires": [ [ "0e02a8c5b8713878" ] ] }, { "id": "d9368294d9621a30", "type": "change", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "Enable battery charge", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 820, "y": 120, "wires": [ [ "b99a5fcf56fa30db" ] ] }, { "id": "6c3cb62857c3f0cc", "type": "change", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "Disable battery charge", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "false", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 820, "y": 160, "wires": [ [ "b99a5fcf56fa30db" ] ] }, { "id": "cc1bdb4e806c49d3", "type": "inject", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "Set", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 110, "y": 480, "wires": [ [ "08f1fa9012a05ea5", "7dcab65894d85d27", "805b9497e42fd964" ] ] }, { "id": "08f1fa9012a05ea5", "type": "subflow:93f485839dfa27a8", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "Süd", "env": [ { "name": "latitude", "value": "51.0618535", "type": "num" }, { "name": "longitude", "value": "7.376629", "type": "num" }, { "name": "declination", "value": "40", "type": "num" }, { "name": "azimuth", "value": "182", "type": "num" }, { "name": "modules power", "value": "9", "type": "num" }, { "name": "apikey", "type": "cred" }, { "name": "watt", "value": "watt_hours_day", "type": "str" }, { "name": "showtoday", "type": "bool", "value": "false" }, { "name": "daystoforecast", "value": "1", "type": "str" }, { "name": "widengraph", "type": "bool", "value": "false" } ], "x": 230, "y": 480, "wires": [ [ "c4d7dd8d06fa28f9" ], [] ] }, { "id": "c4d7dd8d06fa28f9", "type": "function", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "f1", "func": "var pvf = msg.payload;\nvar date = moment().tz(\"Europe/Berlin\");\nvar today = date.format('YYYY-MM-DD');\nvar hourEntries = Object.keys(pvf.result);\nvar todaysEntries = hourEntries.filter(x => x.startsWith(today));\nvar expectedEarning = pvf.result[todaysEntries[todaysEntries.length -1]];\nmsg.payload = expectedEarning;\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [ { "var": "moment", "module": "moment" } ], "x": 390, "y": 460, "wires": [ [ "1d46f7e375b6f7e2" ] ] }, { "id": "0e39db21507d2496", "type": "switch", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "", "property": "payload", "propertyType": "msg", "rules": [ { "t": "lt", "v": "2000", "vt": "str" }, { "t": "btwn", "v": "2000", "vt": "num", "v2": "5000", "v2t": "num" }, { "t": "btwn", "v": "5000", "vt": "num", "v2": "8000", "v2t": "num" }, { "t": "gt", "v": "8000", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 4, "x": 890, "y": 480, "wires": [ [ "db9a8c492c1eacbf" ], [ "af5c4e99e154bf35" ], [ "0d520e8869dda085" ], [ "162844c501bda2cb" ] ] }, { "id": "db9a8c492c1eacbf", "type": "change", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "SOC 100", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "100", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1040, "y": 420, "wires": [ [ "3d56edb712404a94" ] ] }, { "id": "af5c4e99e154bf35", "type": "change", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "SOC 60", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "60", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1040, "y": 460, "wires": [ [ "3d56edb712404a94" ] ] }, { "id": "0d520e8869dda085", "type": "change", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "SOC 40", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "40", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1040, "y": 500, "wires": [ [ "3d56edb712404a94" ] ] }, { "id": "162844c501bda2cb", "type": "change", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "SOC 20", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "20", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1040, "y": 540, "wires": [ [ "3d56edb712404a94" ] ] }, { "id": "29adc486d67dc5b4", "type": "comment", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "solar forecast lesen", "info": "", "x": 230, "y": 420, "wires": [] }, { "id": "70bc14a931ad4c71", "type": "comment", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "daten für den Tag aufbereiten", "info": "", "x": 460, "y": 640, "wires": [] }, { "id": "df70959a7049e70c", "type": "comment", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "Daten jede Stunde lesen", "info": "", "x": 170, "y": 640, "wires": [] }, { "id": "0740f2f6d8be4dc3", "type": "comment", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "je nach Leistung SOC für Batterie festlegen", "info": "", "x": 1020, "y": 620, "wires": [] }, { "id": "c0f098512f61f09e", "type": "ioBroker out", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "Discharging Cutoff SOC [batUseCap]", "topic": "alpha-ess.0.Settings_Discharge.Discharging_Cutoff_SOC", "ack": "false", "autoCreate": "false", "stateName": "", "role": "", "payloadType": "", "readonly": "", "stateUnit": "", "stateMin": "", "stateMax": "", "x": 1330, "y": 480, "wires": [] }, { "id": "db2f79c5ba46ec03", "type": "comment", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "Wert an IOBroker geben", "info": "", "x": 1310, "y": 620, "wires": [] }, { "id": "8cdb8e157b315411", "type": "change", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "topic = soll", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "soll", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1250, "y": 420, "wires": [ [ "0e02a8c5b8713878", "bb6880f6962e941b" ] ] }, { "id": "3ccafa7058527caf", "type": "debug", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "Charging", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1440, "y": 80, "wires": [] }, { "id": "bb6880f6962e941b", "type": "debug", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "Cutoff", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1450, "y": 420, "wires": [] }, { "id": "b99a5fcf56fa30db", "type": "rbe", "z": "11da2ee7fe92bba9", "g": "882f920692db15ac", "name": "Nur einmal", "func": "rbe", "gap": "", "start": "", "inout": "out", "septopics": true, "property": "payload", "topi": "topic", "x": 1030, "y": 120, "wires": [ [ "3ccafa7058527caf" ] ] }, { "id": "7dcab65894d85d27", "type": "subflow:93f485839dfa27a8", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "Ost", "env": [ { "name": "latitude", "value": "51.0618535", "type": "num" }, { "name": "longitude", "value": "7.376629", "type": "num" }, { "name": "declination", "value": "45", "type": "num" }, { "name": "azimuth", "value": "90", "type": "num" }, { "name": "modules power", "value": "2", "type": "num" }, { "name": "apikey", "type": "cred" }, { "name": "watt", "value": "watt_hours_day", "type": "str" }, { "name": "showtoday", "type": "bool", "value": "false" }, { "name": "daystoforecast", "value": "1", "type": "str" }, { "name": "widengraph", "type": "bool", "value": "false" } ], "x": 230, "y": 540, "wires": [ [ "af50b69abaa6e3f2" ], [] ] }, { "id": "805b9497e42fd964", "type": "subflow:93f485839dfa27a8", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "West", "env": [ { "name": "latitude", "value": "51.0618535", "type": "num" }, { "name": "longitude", "value": "7.376629", "type": "num" }, { "name": "declination", "value": "45", "type": "num" }, { "name": "azimuth", "value": "270", "type": "num" }, { "name": "modules power", "value": "3", "type": "num" }, { "name": "apikey", "type": "cred" }, { "name": "watt", "value": "watt_hours_day", "type": "str" }, { "name": "showtoday", "type": "bool", "value": "false" }, { "name": "daystoforecast", "value": "1", "type": "str" }, { "name": "widengraph", "type": "bool", "value": "false" } ], "x": 230, "y": 600, "wires": [ [ "0217fa6ea639b794" ], [] ] }, { "id": "af50b69abaa6e3f2", "type": "function", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "f2", "func": "var pvf = msg.payload;\nvar date = moment().tz(\"Europe/Berlin\");\nvar today = date.format('YYYY-MM-DD');\nvar hourEntries = Object.keys(pvf.result);\nvar todaysEntries = hourEntries.filter(x => x.startsWith(today));\nvar expectedEarning = pvf.result[todaysEntries[todaysEntries.length -1]];\nmsg.payload = expectedEarning;\nmsg.topic = expectedEarning;\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [ { "var": "moment", "module": "moment" } ], "x": 390, "y": 520, "wires": [ [ "6def2e19d5482654" ] ] }, { "id": "0217fa6ea639b794", "type": "function", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "f3", "func": "var pvf = msg.payload;\nvar date = moment().tz(\"Europe/Berlin\");\nvar today = date.format('YYYY-MM-DD');\nvar hourEntries = Object.keys(pvf.result);\nvar todaysEntries = hourEntries.filter(x => x.startsWith(today));\nvar expectedEarning = pvf.result[todaysEntries[todaysEntries.length -1]];\nmsg.payload = expectedEarning;\nmsg.topic = expectedEarning;\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [ { "var": "moment", "module": "moment" } ], "x": 390, "y": 580, "wires": [ [ "a3feba0d2f7707c9" ] ] }, { "id": "a3feba0d2f7707c9", "type": "change", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "L3", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "L3", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 550, "y": 580, "wires": [ [ "043c5238cb193231" ] ] }, { "id": "6def2e19d5482654", "type": "change", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": " L2", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "L2", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 550, "y": 520, "wires": [ [ "043c5238cb193231" ] ] }, { "id": "1d46f7e375b6f7e2", "type": "change", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "L1", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "L1", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 550, "y": 460, "wires": [ [ "043c5238cb193231" ] ] }, { "id": "043c5238cb193231", "type": "join", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "", "mode": "custom", "build": "object", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": true, "timeout": "", "count": "3", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "", "reduceFixup": "", "x": 730, "y": 480, "wires": [ [ "0e39db21507d2496" ] ] }, { "id": "98639d190c555169", "type": "comment", "z": "11da2ee7fe92bba9", "g": "8885f238d46c98d4", "name": "werte addieren", "info": "", "x": 620, "y": 420, "wires": [] } ]
-
Also Du fügst in der JOIN Node ja nur die 3 Werte in ein Objekt zusammen. Wenn Du eine DebugNode hinter die JOIN Node machen würdest würdest Du sehen, wie das Objekt zusammengesetzt wird.
Also die Verwendung von Debug Nodes hilft in der Regel immer.
Die JOIN Node setzt also die topics nur zusammen, addiert diese aber nicht, dass musst Du mit einer anschliessenden ChangeNode noch machen.
das kannst Du entweder in diesem Fall mit der Summenfunktion von JSONATA machen:
oder in dem Du die Werte einzeln mit JSONATA addierst:
Also in JSONATA in der ChangeNode entweder:
payload.L1 + payload.L2 +payload.L3
oder
$sum(payload.*)
hier die Change node