ATON-Heizstab der Technischen Alternative per nodeRED ansteuern

Antworten
Gero
Beiträge: 2368
Registriert: Sa Feb 20, 2021 9:55 am

ATON-Heizstab der Technischen Alternative per nodeRED ansteuern

Beitrag von Gero »

Nach elendig langem hin- und her habe ich es nun geschafft, einen modbus-Server aufzusetzen, mit dem ich über den C.M.I. der TA den Überschuss aus der openWB in das dortige Universum bekomme.

Ich fange gleich mal mit dem Flow an: (es braucht node-red-contrib-modbus)
atl .jpg
Eigentlich sind es drei Flows:
  • Ganz oben mit den Inject-Nodes ist der Modbus-Server (ohne flex, ich habe ja nur zwei Bytes) Für Tests schreibt die Inject-Node einen numerischen Wert in die erste Funktion, die aus dem Wert ein zwei-elementiges Array mit den beiden Bytes für einen 16-bittigen signed Int im little Endian Format macht. Dieses Array wird dann in der nächsten Funktion in den Server als holding-Register geschrieben.
  • Ein bisschen drunter ist ein eigentlich überflüssiger Modbus-Client, der zeigt aber ganz schön, was da gerade so im Server für Werte stehen. Die beiden sind über den Port 502 auf localhost miteinander verbunden.
  • Der letzte Flow ist der Endpunkt für die Leistungsabfrage das smarthome2.0-http-Geräts. Dem wird von der openWB die zu verbrauchende Leistung mitgegeben und diese wird in der ersten Funktion herausgelesen und in den Modbus-Server geschrieben. Im weiteren Verlauf muss noch die Leistungsaufnahme des Heizstabs ermittelt werden, das passiert per HTTP-Request auf den zur Leistungsmessung verbauten Shelly 1PM. Wenn man mit der Funktion "Energiemanager" arbeitet, dann könnte man sicherlich auch die verbrauchte Leistung aus der TA-Welt wieder aus dem CMI importieren, allerdings erfüllt die openWB bereits die Aufgabe des Energiemanagers. Die Vorgabewerte sind auch nur theoretischer Natur, die Leistungsaufnahme in der echten Welt sind um einiges geringer. (Das habe ich mit dem 1pm, einem 2em und einer homematic-Steckdose verifiziert: Aus 3000W Leistung werden gemessen nur so um die 2800W. Laut TA gehört das so wegen erlaubter Streuungen bei den Bauteilen).
Hier noch die Einstellung auf dem CMI:
cmi.jpg
Eine Anmerkung noch zum verwendeten Port: Seitens CMI kann der unter "Ethernet" eingestellt werden, gilt dann aber für alle modbus-Verbindungen. Default ist 502 und der ist bei nodeRED auf einer eigenen Raspi-Installation nicht erreichbar, denn der nodeRED-Prozess läuft als user "pi" und der darf erst ab Port 1024 ran. Hier muss man entweder sich auf einen anderen Port (z.B. 10502) einigen oder nodeRED als root laufen lassen. Bei mir läuft nodeRED als REDmatic auf der homematic-CCU und da gibt es das Problem nicht. Hier sind auch die http-Endpunkte ein bisschen anders als auf einer normalen nodeRED-Installation hier kommt ein "addons/red" davor, wohingegen bei einer Raspi-Installation auf Port 1880 statt 80 gelauscht wird. Die IP-Adresse 192.168.8.2 heisst an allen anderen Stellen ccu.fritz.box - das kann TA leider nicht.

Und hier noch das smarthome2.0-Gerät:
sh20.jpg
Aus historischen Gründen habe ich hier als Ein-Aus-Schalter noch einen Shelly 1 drin, der bei einem Regler einen Digital-Eingang zur Freigabe der Pufferheizung schaltet. Mit dieser 1/0 schalte ich dann die Funktion "Leistungsregler" in Zwangsbetrieb und die Vorgabe-Leistung kommt über den CMI als Analogwert. Eine Nutzung des Energiemanagers verbietet sich, da der erwartet, dass sich die zu verbratende Leistung um die Vorgabe reduziert wird. Das ist der richtige Weg, wenn man das TA-Zählermodul verwendet, mit einer Vorgabe aus der openWB wird das nur kompliziert. Hier der Leistungsregler - eigentlich stellt man da nur die min- und max-Leistung ein, der Rest ist Default.
leistungsregler.jpg
Der Regler selbst ist ein RSM610, der Ausgang an dem der ATON angeschlossen ist, steht auf PWM: (Wichtig ist die 1000 bei Eingangswert 2 - mit den erwartet angenommenen 100 sind's um eine Größenordnung zu wenig Watts)
ausgang.jpg
Zu guter Letzt noch den Flow für den einfachen Import:

Code: Alles auswählen

[{"id":"ba6bd7e6.cd6d48","type":"modbus-server","z":"b8ffe81b.38e0c8","name":"","logEnabled":false,"hostname":"0.0.0.0","serverPort":"502","responseDelay":100,"delayUnit":"ms","coilsBufferSize":"0","holdingBufferSize":"8","inputBufferSize":"0","discreteBufferSize":"0","showErrors":true,"x":820,"y":100,"wires":[["aface45f.0de24"],[],[],[],[]]},{"id":"7ef3011c.be2738","type":"inject","z":"b8ffe81b.38e0c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1500","payloadType":"num","x":110,"y":180,"wires":[["bf859d30.7ba0a"]]},{"id":"5a99fd48.c44c04","type":"function","z":"b8ffe81b.38e0c8","name":"set_holding","func":"\nvar a = new Int16Array(2);\n\na = msg.payload;\n\nmsg.payload = {\n    'value': [ a[0], a[1] ],\n    'register': 'holding', \n    'address': 0 , \n    'disableMsgOutput' : 0 \n}; \nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":610,"y":120,"wires":[["c32d5414.fc92a","ba6bd7e6.cd6d48"]]},{"id":"841b64ab.cc7be8","type":"modbus-read","z":"b8ffe81b.38e0c8","d":true,"name":"","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"0","dataType":"HoldingRegister","adr":"0","quantity":"2","rate":"3","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"ee8487e.a76e878","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":550,"y":320,"wires":[[],["aa7bb0e0.105b78","bab5d2c7.0b9558"]]},{"id":"aa7bb0e0.105b78","type":"modbus-response","z":"b8ffe81b.38e0c8","name":"","registerShowMax":"2","x":830,"y":280,"wires":[]},{"id":"bf859d30.7ba0a","type":"function","z":"b8ffe81b.38e0c8","name":"calc_big_endian","func":"\n\nvar m1 = {};\nvar m2 = {};\n\nvar a = new Int16Array(2);\n\nvar n = msg.payload;\nvar neg = false;\n\nvar p = Math.pow(2,16) / 2;\n\n// Eingabe auf Minimum und Maximum kappen\n// positiv ist 0...32.767\nif (n > p - 1){\n    n = p - 1;\n}\n\n// negativ ist -32.768...-1\nif ( n < 0 ) {\n    neg = true;\n    if (n <= -1 * p ) {\n      n = p;\n      }\n    else {\n        n = -n;\n    }\n}\n\n// konvertieren nach hex\nvar s = n.toString(16);\n\n// vierstellig machen, damit stringweise schön nach \n// LSB und MSB getrennt werden kann\ns = \"000\" + s;\ns = s.slice(s.length - 4, s.length);\n\nvar b0 = s.slice(0, 2);  // MSB\nvar b1 = s.slice(2, 4);  // LSB \n\nif (neg){\n    // 0,128 = -32.768; 255,255 = -1\n    // bei negativen Zahlen wird von 255 heruntergezählt:\n    a[0] = 255 - parseInt(b0,16) + 1;\n    if ( a[0] == 256 ){ // overflow\n        a[0] = 255;\n    }\n    a[1] = 255 - parseInt(b1,16); \n    if ( a[1] == 256 ){ // overflow\n        a[1] = 255;\n    }\n}\nelse {\n    // 255,127 = 32.767\n    //positive Zahlen zählen wie sonst auch 0...255\n    a[0] = parseInt(b0,16);\n    a[1] = parseInt(b1,16);\n}    \n\nm1.payload = a;\nm2.payload = s;\nreturn [m1, m2]","outputs":2,"noerr":0,"initialize":"","finalize":"","x":380,"y":100,"wires":[["5a99fd48.c44c04","de3cdc1a.b14838"],[]]},{"id":"b338ee58.2597c","type":"inject","z":"b8ffe81b.38e0c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":110,"y":60,"wires":[["bf859d30.7ba0a"]]},{"id":"ff4ba88d.77abe","type":"inject","z":"b8ffe81b.38e0c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"300","payloadType":"num","x":110,"y":100,"wires":[["bf859d30.7ba0a"]]},{"id":"2496d4f4.5ba07c","type":"inject","z":"b8ffe81b.38e0c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1700","payloadType":"num","x":110,"y":220,"wires":[["bf859d30.7ba0a"]]},{"id":"44a2e09c.0f4148","type":"function","z":"b8ffe81b.38e0c8","name":"","func":"var m = msg;\n\nvar w;\n\nif (msg.req.query.watt === undefined ){\n    w = \"0\";\n}\nelse{\n    w = msg.req.query.watt;\n}\n\nm.payload = Number(w);\n\nreturn m;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":480,"wires":[["33d4078a.9ff1a8","13aa1d0a.4da8cb","bf859d30.7ba0a"]]},{"id":"2c8d77bc.893b9","type":"http in","z":"b8ffe81b.38e0c8","name":"","url":"/heizstab","method":"get","upload":false,"swaggerDoc":"","x":160,"y":480,"wires":[["44a2e09c.0f4148"]]},{"id":"af8ddf23.6b6ba8","type":"function","z":"b8ffe81b.38e0c8","name":"","func":"var w = msg.payload.meters[0].power;\nif (w === undefined){\n    msg.payload = 0;\n}    \nelse{    \n    msg.payload = Math.trunc(w);\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":800,"y":480,"wires":[["5dfb331f.2b7ddc","cfb321a7.bf72e"]]},{"id":"13aa1d0a.4da8cb","type":"http request","z":"b8ffe81b.38e0c8","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"192.168.8.24/status","tls":"","persist":false,"proxy":"","authType":"","x":590,"y":480,"wires":[["af8ddf23.6b6ba8"]]},{"id":"33d4078a.9ff1a8","type":"debug","z":"b8ffe81b.38e0c8","name":"heizstab_setW","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":600,"y":540,"wires":[]},{"id":"5dfb331f.2b7ddc","type":"debug","z":"b8ffe81b.38e0c8","name":"heizstab_getW","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1020,"y":540,"wires":[]},{"id":"aface45f.0de24","type":"debug","z":"b8ffe81b.38e0c8","name":"modbus_buffer","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1060,"y":180,"wires":[]},{"id":"1f0b2e4c.d2bd22","type":"inject","z":"b8ffe81b.38e0c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"990","payloadType":"num","x":110,"y":140,"wires":[["bf859d30.7ba0a"]]},{"id":"e4c4e652.1e6e6","type":"inject","z":"b8ffe81b.38e0c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"3000","payloadType":"num","x":110,"y":260,"wires":[["bf859d30.7ba0a"]]},{"id":"de3cdc1a.b14838","type":"debug","z":"b8ffe81b.38e0c8","name":"hex-out","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":600,"y":180,"wires":[]},{"id":"c32d5414.fc92a","type":"debug","z":"b8ffe81b.38e0c8","name":"holding_out","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":810,"y":180,"wires":[]},{"id":"bab5d2c7.0b9558","type":"debug","z":"b8ffe81b.38e0c8","name":"modbus_read","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":820,"y":360,"wires":[]},{"id":"998b4d29.d6f7e8","type":"inject","z":"b8ffe81b.38e0c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"3600","payloadType":"num","x":110,"y":300,"wires":[["bf859d30.7ba0a"]]},{"id":"cfb321a7.bf72e","type":"http response","z":"b8ffe81b.38e0c8","name":"","statusCode":"","headers":{},"x":990,"y":480,"wires":[]},{"id":"ee8487e.a76e878","type":"modbus-client","name":"modbus-local","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"tcpHost":"127.0.0.1","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":1,"commandDelay":1,"clientTimeout":1000,"reconnectOnTimeout":true,"reconnectTimeout":2000,"parallelUnitIdsAllowed":true}]
Es läuft gerade mal so produktiv, Erfahrungswerte fehlen noch. Das hier sollte aber allen Interessierten schon einmal genug Einstiegshilfe bieten. Auch wenn's kein Heizstab von TA ist, sondern irgendein anderer mit Leistungsvorgabe von außen. Oder eine Wärmepumpe.

edit: Update des Flows und aktualisierte Screenshots einer neuen Version nach der Winterpause.
Zuletzt geändert von Gero am Di Feb 28, 2023 6:42 pm, insgesamt 2-mal geändert.
openWB-series2, openWB-Buchse, E3/DC S10pro+19.5kWh, 30kWp Ost-Süd, Model 3 und Ion
aiole
Beiträge: 6779
Registriert: Mo Okt 08, 2018 4:51 pm

Re: ATON-Heizstab der Technischen Alternative per nodeRED ansteuern

Beitrag von aiole »

sehr cool! (oder hot!)

Sieht nach ganz schön Handstand aus, aber TA ist was die Netzwerkanbindung angeht - sagen wir - "etwas konservativ".
Mit dem CMI läuft es zumindest einigermaßen und bezogen auf das Produktportfolio geht es auch viel mehr um solide Regelungstechnik als Vernetzung. Dahingehend ist TA schon eine solide Wahl.

Kann ich den 485 to 0...10V-Konverter wieder einpacken :lol: ?
Gero
Beiträge: 2368
Registriert: Sa Feb 20, 2021 9:55 am

Re: ATON-Heizstab der Technischen Alternative per nodeRED ansteuern

Beitrag von Gero »

aiole hat geschrieben: Mo Sep 19, 2022 4:54 pm Kann ich den 485 to 0...10V-Konverter wieder einpacken :lol: ?
Den auf jeden Fall, dafür müsste ich mir ja erst noch einen 0-10V Eingang dazukaufen. Frei wäre noch ein PT1000, also Widerstand.

Mach‘ ich aber erst, wenn sich herausstellen sollte, dass die 20s-Pollintervall zu lang sind. Glaub‘ ich aber erst mal nicht dran.
openWB-series2, openWB-Buchse, E3/DC S10pro+19.5kWh, 30kWp Ost-Süd, Model 3 und Ion
aiole
Beiträge: 6779
Registriert: Mo Okt 08, 2018 4:51 pm

Re: ATON-Heizstab der Technischen Alternative per nodeRED ansteuern

Beitrag von aiole »

Gero hat geschrieben: Mo Sep 19, 2022 5:45 pm ..., dass die 20s-Pollintervall zu lang sind. Glaub‘ ich aber erst mal nicht dran.
Ich auch nicht. Nicht bei einem Heizstab.
Becker
Beiträge: 765
Registriert: Mi Okt 07, 2020 4:34 pm

Re: ATON-Heizstab der Technischen Alternative per nodeRED ansteuern

Beitrag von Becker »

für Modbus (lesen/schreiben) würde ich dir empfehlen den Bufferparser zu nutzen, vereinfacht vieles ungemein. :!:
openWB series2 Buchse (2021)
go-eCharger HOME+ 22 kW (2022)
Gero
Beiträge: 2368
Registriert: Sa Feb 20, 2021 9:55 am

Re: ATON-Heizstab der Technischen Alternative per nodeRED ansteuern

Beitrag von Gero »

Hast du mal einen Link oder Besipiel für den Bufferparser?
openWB-series2, openWB-Buchse, E3/DC S10pro+19.5kWh, 30kWp Ost-Süd, Model 3 und Ion
Becker
Beiträge: 765
Registriert: Mi Okt 07, 2020 4:34 pm

Re: ATON-Heizstab der Technischen Alternative per nodeRED ansteuern

Beitrag von Becker »

ist nun ab Werk installiert. Falls du eine veralterte Version verwendest "node-red-contrib-buffer-parser" installieren.

schau dir mal meine Flows an:

Code: Alles auswählen

[
    {
        "id": "cfd863f1.9b6cd",
        "type": "modbus-getter",
        "z": "32e1a23f.66043e",
        "name": "10100 - 10116",
        "showStatusActivities": false,
        "showErrors": false,
        "logIOActivities": false,
        "unitid": "1",
        "dataType": "InputRegister",
        "adr": "10100",
        "quantity": "17",
        "server": "67bef580.136134",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 120,
        "y": 120,
        "wires": [
            [
                "ff9d62d3.d8eb1"
            ],
            []
        ]
    },
    {
        "id": "ff9d62d3.d8eb1",
        "type": "buffer-parser",
        "z": "32e1a23f.66043e",
        "name": "Ladepunkt 1",
        "data": "responseBuffer.buffer",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "int32be",
                "name": "P",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int32be",
                "name": "W",
                "offset": 4,
                "length": 1,
                "offsetbit": 0,
                "scale": "0.001",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "U1",
                "offset": 8,
                "length": 1,
                "offsetbit": 0,
                "scale": "0.01",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "U2",
                "offset": 10,
                "length": 1,
                "offsetbit": 0,
                "scale": "0.01",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "U3",
                "offset": 12,
                "length": 1,
                "offsetbit": 0,
                "scale": "0.01",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "I1",
                "offset": 14,
                "length": 1,
                "offsetbit": 0,
                "scale": "0.01",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "I2",
                "offset": 16,
                "length": 1,
                "offsetbit": 0,
                "scale": "0.01",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "I3",
                "offset": 18,
                "length": 1,
                "offsetbit": 0,
                "scale": "0.01",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "LP1 Charge Point Configured",
                "offset": 20,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "LP1 Chargepoint enabled",
                "offset": 22,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int32be",
                "name": "LP1 last used RFID Tag",
                "offset": 24,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "LP1 Plugged Status",
                "offset": 28,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "LP1 Charging Active",
                "offset": 30,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "LP1 Actual A Configured",
                "offset": 32,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "keyvalue",
        "resultTypeType": "output",
        "multipleResult": false,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 350,
        "y": 120,
        "wires": [
            [
                "f02d0e67.bea6c8",
                "2d2868bde4f0bc07",
                "ace8fc32d3a0b483",
                "59fe197a39cb5713",
                "22de283e0971e848",
                "e9eaa97e74e9e9ea"
            ]
        ]
    },
    {
        "id": "67bef580.136134",
        "type": "modbus-client",
        "name": "openWB",
        "clienttype": "tcp",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "tcpHost": "192.168.168.51",
        "tcpPort": "502",
        "tcpType": "TCP-RTU-BUFFERED",
        "serialPort": "/dev/ttyUSB",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": "9600",
        "serialDatabits": "8",
        "serialStopbits": "1",
        "serialParity": "none",
        "serialConnectionDelay": "100",
        "serialAsciiResponseStartDelimiter": "",
        "unit_id": 1,
        "commandDelay": 50,
        "clientTimeout": 1000,
        "reconnectOnTimeout": true,
        "reconnectTimeout": 2000,
        "parallelUnitIdsAllowed": false
    }
]
oder schreiben:

Code: Alles auswählen

[
    {
        "id": "eada0bf7.5d6e88",
        "type": "buffer-maker",
        "z": "2bd6dc17.504c44",
        "name": "",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "name": "item1",
                "type": "uint32be",
                "length": 1,
                "dataType": "msg",
                "data": "payload"
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "x": 390,
        "y": 660,
        "wires": [
            [
                "c1d92794.ac616"
            ]
        ]
    },
    {
        "id": "c1d92794.ac616",
        "type": "buffer-parser",
        "z": "2bd6dc17.504c44",
        "name": "",
        "data": "payload",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "uint16be",
                "name": "data",
                "offset": 0,
                "length": 2,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "value",
        "resultTypeType": "output",
        "multipleResult": true,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 670,
        "y": 660,
        "wires": [
            [
                "1379db1.7bc5f25",
                "875c8999.2c974"
            ]
        ]
    },
    {
        "id": "1379db1.7bc5f25",
        "type": "modbus-write",
        "z": "2bd6dc17.504c44",
        "name": "40795",
        "showStatusActivities": false,
        "showErrors": true,
        "unitid": "3",
        "dataType": "MHoldingRegisters",
        "adr": "40795",
        "quantity": "2",
        "server": "b6c6500c.41cc1",
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 850,
        "y": 660,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "b6c6500c.41cc1",
        "type": "modbus-client",
        "name": "SBS2.5",
        "clienttype": "tcp",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "tcpHost": "192.168.168.55",
        "tcpPort": "502",
        "tcpType": "TCP-RTU-BUFFERED",
        "serialPort": "/dev/ttyUSB",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": "9600",
        "serialDatabits": "8",
        "serialStopbits": "1",
        "serialParity": "none",
        "serialConnectionDelay": "100",
        "serialAsciiResponseStartDelimiter": "",
        "unit_id": 3,
        "commandDelay": 10,
        "clientTimeout": 1000,
        "reconnectOnTimeout": true,
        "reconnectTimeout": 2000,
        "parallelUnitIdsAllowed": false
    }
]
oder SDM 72v2:

Code: Alles auswählen

[
    {
        "id": "8a5957b7b2f7ec03",
        "type": "modbus-getter",
        "z": "112d382639b7cc28",
        "name": "0006 - 0035",
        "showStatusActivities": false,
        "showErrors": true,
        "logIOActivities": false,
        "unitid": "1",
        "dataType": "InputRegister",
        "adr": "0006",
        "quantity": "30",
        "server": "bb0f2e018eb97236",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 190,
        "y": 100,
        "wires": [
            [
                "f20df6cb188e76a4"
            ],
            [
                "b267ca8a8b7f6dcb"
            ]
        ]
    },
    {
        "id": "b267ca8a8b7f6dcb",
        "type": "modbus-getter",
        "z": "112d382639b7cc28",
        "name": "0052 - 0053",
        "showStatusActivities": false,
        "showErrors": true,
        "logIOActivities": false,
        "unitid": "1",
        "dataType": "InputRegister",
        "adr": "0052",
        "quantity": "2",
        "server": "bb0f2e018eb97236",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 190,
        "y": 160,
        "wires": [
            [
                "e58032fe783749bd"
            ],
            [
                "268716dd0510b280"
            ]
        ]
    },
    {
        "id": "e58032fe783749bd",
        "type": "buffer-parser",
        "z": "112d382639b7cc28",
        "name": "P",
        "data": "payload",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "floatbe",
                "name": "P",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "value",
        "resultTypeType": "output",
        "multipleResult": true,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 370,
        "y": 160,
        "wires": [
            [
                "e8a3a2b877a16254"
            ]
        ]
    },
    {
        "id": "268716dd0510b280",
        "type": "modbus-getter",
        "z": "112d382639b7cc28",
        "name": "0060 - 0063",
        "showStatusActivities": false,
        "showErrors": true,
        "logIOActivities": false,
        "unitid": "1",
        "dataType": "InputRegister",
        "adr": "0060",
        "quantity": "4",
        "server": "bb0f2e018eb97236",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 190,
        "y": 220,
        "wires": [
            [
                "a4cf714520032bd0"
            ],
            [
                "c7d78de48b6972f0"
            ]
        ]
    },
    {
        "id": "a4cf714520032bd0",
        "type": "buffer-parser",
        "z": "112d382639b7cc28",
        "name": "Q, PF",
        "data": "payload",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "floatbe",
                "name": "Q",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "-1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "PF",
                "offset": 4,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "value",
        "resultTypeType": "output",
        "multipleResult": true,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 370,
        "y": 220,
        "wires": [
            [
                "e8a3a2b877a16254"
            ]
        ]
    },
    {
        "id": "c7d78de48b6972f0",
        "type": "modbus-getter",
        "z": "112d382639b7cc28",
        "name": "0070 - 0075",
        "showStatusActivities": false,
        "showErrors": true,
        "logIOActivities": false,
        "unitid": "1",
        "dataType": "InputRegister",
        "adr": "0070",
        "quantity": "6",
        "server": "bb0f2e018eb97236",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 190,
        "y": 280,
        "wires": [
            [
                "2ae4692b297de57f"
            ],
            [
                "3a7729b29e4a9e67"
            ]
        ]
    },
    {
        "id": "2ae4692b297de57f",
        "type": "buffer-parser",
        "z": "112d382639b7cc28",
        "name": "Hz, W",
        "data": "payload",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "floatbe",
                "name": "Hz",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "W_imp",
                "offset": 4,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "W_exp",
                "offset": 8,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "value",
        "resultTypeType": "output",
        "multipleResult": true,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 370,
        "y": 280,
        "wires": [
            [
                "e8a3a2b877a16254"
            ]
        ]
    },
    {
        "id": "3a7729b29e4a9e67",
        "type": "modbus-getter",
        "z": "112d382639b7cc28",
        "name": "0224 - 0225",
        "showStatusActivities": false,
        "showErrors": true,
        "logIOActivities": false,
        "unitid": "1",
        "dataType": "InputRegister",
        "adr": "0224",
        "quantity": "2",
        "server": "bb0f2e018eb97236",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 190,
        "y": 340,
        "wires": [
            [
                "19f9bcad6ccfb90d"
            ],
            [
                "44049c9369ec07d6"
            ]
        ]
    },
    {
        "id": "19f9bcad6ccfb90d",
        "type": "buffer-parser",
        "z": "112d382639b7cc28",
        "name": "I Neutral",
        "data": "payload",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "floatbe",
                "name": "I_N",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "value",
        "resultTypeType": "output",
        "multipleResult": true,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 380,
        "y": 340,
        "wires": [
            [
                "e8a3a2b877a16254"
            ]
        ]
    },
    {
        "id": "e8a3a2b877a16254",
        "type": "join",
        "z": "112d382639b7cc28",
        "name": "",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "22",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 550,
        "y": 220,
        "wires": [
            [
                "72eeac8f0851a096"
            ]
        ]
    },
    {
        "id": "f20df6cb188e76a4",
        "type": "buffer-parser",
        "z": "112d382639b7cc28",
        "name": "I, P, S, Q, PF L1-3",
        "data": "payload",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "floatbe",
                "name": "I1",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "I2",
                "offset": 4,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "I3",
                "offset": 8,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "P1",
                "offset": 12,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "P2",
                "offset": 16,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "P3",
                "offset": 20,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "S1",
                "offset": 24,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "S2",
                "offset": 28,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "S3",
                "offset": 32,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "Q1",
                "offset": 36,
                "length": 1,
                "offsetbit": 0,
                "scale": "-1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "Q2",
                "offset": 40,
                "length": 1,
                "offsetbit": 0,
                "scale": "-1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "Q3",
                "offset": 44,
                "length": 1,
                "offsetbit": 0,
                "scale": "-1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "PF1",
                "offset": 48,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "PF2",
                "offset": 52,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "floatbe",
                "name": "PF3",
                "offset": 56,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "value",
        "resultTypeType": "output",
        "multipleResult": true,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 410,
        "y": 100,
        "wires": [
            [
                "e8a3a2b877a16254"
            ]
        ]
    },
    {
        "id": "72eeac8f0851a096",
        "type": "function",
        "z": "112d382639b7cc28",
        "name": "Ausgabe",
        "func": "let P = parseFloat(msg.payload.P.toFixed(1));\nlet P1 = parseFloat(msg.payload.P1.toFixed(1));\nlet P2 = parseFloat(msg.payload.P2.toFixed(1));\nlet P3 = parseFloat(msg.payload.P3.toFixed(1));\nlet I1 = parseFloat(msg.payload.I1.toFixed(2));\nlet I2 = parseFloat(msg.payload.I2.toFixed(2));\nlet I3 = parseFloat(msg.payload.I3.toFixed(2));\nlet I_N = parseFloat(msg.payload.I_N.toFixed(2));\nlet Q = Math.round(msg.payload.Q);\nlet Q1 = Math.round(msg.payload.Q1);\nlet Q2 = Math.round(msg.payload.Q2);\nlet Q3 = Math.round(msg.payload.Q3);\nlet PF = parseFloat(msg.payload.PF.toFixed(2));\nlet PF1 = parseFloat(msg.payload.PF1.toFixed(2));\nlet PF2 = parseFloat(msg.payload.PF2.toFixed(2));\nlet PF3 = parseFloat(msg.payload.PF3.toFixed(2));\nlet W_imp = parseFloat(msg.payload.W_imp.toFixed(2));\nlet Hz = parseFloat(msg.payload.Hz.toFixed(2));\nmsg.payload = {P,P1,P2,P3,I1,I2,I3,I_N,Q,Q1,Q2,Q3,PF,PF1,PF2,PF3,W_imp,Hz};\nmsg.topic = \"Nibe\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 700,
        "y": 220,
        "wires": [
            [
                "db5dcd81364514f5",
                "db6d6610934a93bd",
                "cf2131f573a01812",
                "47cb86327cdd4193",
                "26e3da9f2d23e0ea",
                "52d5b0db78084f15",
                "e6a82cc457521052",
                "8e10c92b9a5ab496",
                "97a1f36aa1e2ec01",
                "19fb595b9173d2c8",
                "c541c6e7a6a7686f",
                "0129e1f5108578f4",
                "ef7f6437411fa07f",
                "6deb35d2c276e985",
                "5f3daa0a5dd5e96b",
                "4a009c01ef0a030d",
                "36c091e5f8e56c46",
                "2f19c00e343455f6"
            ]
        ]
    },
    {
        "id": "bb0f2e018eb97236",
        "type": "modbus-client",
        "name": "SDM",
        "clienttype": "serial",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "failureLogEnabled": false,
        "tcpHost": "127.0.0.1",
        "tcpPort": "502",
        "tcpType": "DEFAULT",
        "serialPort": "/dev/ttyUSB0",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": "9600",
        "serialDatabits": "8",
        "serialStopbits": "1",
        "serialParity": "none",
        "serialConnectionDelay": "5",
        "serialAsciiResponseStartDelimiter": "0x3A",
        "unit_id": 1,
        "commandDelay": 5,
        "clientTimeout": 2000,
        "reconnectOnTimeout": true,
        "reconnectTimeout": 5000,
        "parallelUnitIdsAllowed": false
    }
]
132.jpg
openWB series2 Buchse (2021)
go-eCharger HOME+ 22 kW (2022)
Gero
Beiträge: 2368
Registriert: Sa Feb 20, 2021 9:55 am

Re: ATON-Heizstab der Technischen Alternative per nodeRED ansteuern

Beitrag von Gero »

Nun hab' ich den Eingangspost mal mit einer neuen Version aktualisiert. Die alte hatte noch Bugs, die ich vor der Winterpause nicht mehr korrigieren wollte. Nun scheint die Sonne wieder und es ist hoffentlich nun einsetzbar. Mal schauen, ob das Regelverhalten besser wird, als vorher, wo ich den Überschuss aus dem S10 in den CMI übernommen habe und dort den Überschuss habe verbraten lassen. Das waren ja dann zwei Regler im selben Regelkreis und das hat doch schon deutliche Schwingungen am EVU-Punkt zur Folge gehabt. Deshalb der Aufwand mit nodeRED und dem ganzen Kram. Einfach einen myPV-Heizstab einbauen lassen wäre wahrscheinlich einfacher gewesen - aber einen funktionierenden Heizstab wegschmeissen will ich nun auch nicht.

Vielen Dank @Becker für den Tipp, aber da hatte ich nun schon meine Funktion gebastelt. Ich möchte mal hoffen, dass ich mich nicht noch tiefer in modbus einarbeiten muss. Ist mir schon irgendwie ein bisschen zu stochastisch das Ganze... ;-)
openWB-series2, openWB-Buchse, E3/DC S10pro+19.5kWh, 30kWp Ost-Süd, Model 3 und Ion
Antworten