NEWS
Venus V3.0 API Token
-
@derkleinschreiber sagte in Venus V3.0 API Token:
--> ein bischen Offtopic: Sollte jemand lieber mit Blockly "programmieren" geht das sehr einfach mit exec aufrufen (mit netcat = nc)
echo '{"id":1,"method":"Bat.GetStatus","params":{"id":0}}' | nc -u -w 1 192.168.178.xyz 30000
Alles andere aus der API kann man damit auch abfragen / übertragen / Modes setzen etc. Habs grad probiert. Wichtig ist nur das vorher einmalig :
echo '{ "id": 0, "method": "Marstek.GetDevice", "params": { "ble_mac":"0" } } ' | nc -u -w 1 192.168.178.255 30000 gesendet wird damit er die UDP API aktiviert.
WIe @derkleinschreiber oben sagte, versuche ich, meine Venus E 3.0 (am LAN) und CT002 über die API auszulesen mit netcat.
Venus Version ist V148.
ping auf die Adresse geht.
Wenn ich Kommandos sende erhalte ich auch eine Antwort, alledings immer einen Fehler.
Prinzipiell scheint daher die Venus ja zu antworten.auch nach mehrmaligem Senden von Bat.GetStatus :
Kommando:
MARSTEK_Result=echo '{ "id": 0, "method": "Marstek.GetDevice", "params": { "ble_mac":"0"}} ' | nc -u -w 1 192.168.2.33 30000
Ergebnis:
MARSTEK_Result={ "id": 0, "src": "VenusE 3.0-bc2a33ad06aa", "error": { "code": -32700, "message": "Parse error", "data": 402 } }Hat jemand eine Idee, woran es liegen kann?
Herzlichen Dank für euren Support!
@KSN
setze als ble_mac mal die Bluetoothadresse des Gerätes ein. SIe steht auf dem Aufkleber des Gerätes. So eingeben, wie sie dort steht ... also anstellle der "0" "12ab34cd .."
Irgendwie sehe ich das in der v2.0 Doku der API nicht mehr. Ich hatte nach der v1.0 gearbeitet
Es wird ja mit einem parsing-Fehler geantwortet. Vielleicht musst du die "0" auch ohne "" senden. Ich las mal irgendwo, dass Marstek die Variablentypen auch mal ändert. -
puh weil ich jetzt ewig herumgetan habe, hier meine Tip: Nach dem Ändern der Ports von 30000 auf 2220 ging es. Hab das Script @stephan61 von ChatGPT erweitern lassen. @technogodder das gleiche Problem hatte ich auch. Versuchs mit der Portänderung und folgendem Script:
/*********************** MARSTEK VENUS E UDP erweiterte Version ***********************/ const DEVICE_IP = "192.168.179.103"; const DEVICE_PORT = 2220; const POLL_INTERVAL = 10; // Sekunden const TIMEOUT = 30; // Sekunden bis Gerät als offline gilt const DEBUG = false; const dgram = require("dgram"); let socket = dgram.createSocket("udp4"); let lastResponse = Date.now(); /*********************** STATES ***********************/ const BASE = "0_userdata.0.marstek."; const STATES = { soc: BASE + "battery.soc", batteryPower: BASE + "battery.power", gridPower: BASE + "grid.power", pvPower: BASE + "pv.power", temperature: BASE + "device.temperature", online: BASE + "device.online" }; createState(STATES.soc, 0, { name: "Battery SOC", unit: "%", type: "number", role: "value.battery" }); createState(STATES.batteryPower, 0, { name: "Battery Power", unit: "W", type: "number", role: "value.power" }); createState(STATES.gridPower, 0, { name: "Grid Power", unit: "W", type: "number", role: "value.power" }); createState(STATES.pvPower, 0, { name: "PV Power", unit: "W", type: "number", role: "value.power" }); createState(STATES.temperature, 0, { name: "Temperature", unit: "°C", type: "number", role: "value.temperature" }); createState(STATES.online, false, { name: "Device Online", type: "boolean", role: "indicator.reachable" }); /*********************** JSON RPC REQUESTS ***********************/ const requests = { battery: JSON.stringify({ id: 1, method: "Bat.GetStatus", params: { id: 0 } }), energy: JSON.stringify({ id: 2, method: "ES.GetStatus", params: { id: 0 } }), discover: JSON.stringify({ id: 0, method: "Marstek.GetDevice", params: { ble_mac: "0" } }) }; /*********************** UDP MESSAGE ***********************/ socket.on("message", (msg) => { const text = msg.toString(); if (DEBUG) log("UDP: " + text); lastResponse = Date.now(); setState(STATES.online, true, true); try { const data = JSON.parse(text); if (!data.result) return; const r = data.result; // SOC if (r.soc !== undefined) { setState(STATES.soc, Number(r.soc), true); } if (r.bat_soc !== undefined) { setState(STATES.soc, Number(r.bat_soc), true); } // Batterie Leistung if (r.bat_power !== undefined) { setState(STATES.batteryPower, Number(r.bat_power), true); } // Netzleistung if (r.ongrid_power !== undefined) { setState(STATES.gridPower, Number(r.ongrid_power), true); } // PV Leistung if (r.pv_power !== undefined) { setState(STATES.pvPower, Number(r.pv_power), true); } // Temperatur if (r.temp !== undefined) { setState(STATES.temperature, Number(r.temp), true); } } catch (e) { log("Parse Fehler: " + e, "error"); } }); /*********************** ERROR HANDLING ***********************/ socket.on("error", (err) => { log("UDP Fehler: " + err.message, "error"); }); /*********************** SOCKET START ***********************/ socket.on("listening", () => { const addr = socket.address(); log("Marstek UDP gestartet: " + addr.address + ":" + addr.port); }); socket.bind(); /*********************** POLLING ***********************/ function pollDevice() { try { socket.send(requests.energy, 0, requests.energy.length, DEVICE_PORT, DEVICE_IP); socket.send(requests.battery, 0, requests.battery.length, DEVICE_PORT, DEVICE_IP); } catch (e) { log("Send Fehler: " + e, "error"); } } schedule("*/" + POLL_INTERVAL + " * * * * *", pollDevice); /*********************** DISCOVERY ***********************/ setTimeout(() => { if (DEBUG) log("Discovery Request"); socket.send(requests.discover, 0, requests.discover.length, DEVICE_PORT, DEVICE_IP); }, 5000); /*********************** OFFLINE CHECK ***********************/ setInterval(() => { if (Date.now() - lastResponse > TIMEOUT * 1000) { setState(STATES.online, false, true); } }, 5000); -
Habe nun auch komplett umgeschwenkt auf die Api Steuerung.
Mit der neuen Firmware hatte ich zwar auch die Api Funktion in der App, aber der Speicher hatte nicht geantwortet.
Der Support hatte mir dann neuere Firmware freigeschaltet, und ja hat geklappt, die Speicher kann ich nun via API regeln.
Das Laden hatte via Skript schon mal geklappt, mal sehen, wie es sich nachher verhält, beim endladen. Das neue Skript ist noch "frisch". -
Habe nun auch komplett umgeschwenkt auf die Api Steuerung.
Mit der neuen Firmware hatte ich zwar auch die Api Funktion in der App, aber der Speicher hatte nicht geantwortet.
Der Support hatte mir dann neuere Firmware freigeschaltet, und ja hat geklappt, die Speicher kann ich nun via API regeln.
Das Laden hatte via Skript schon mal geklappt, mal sehen, wie es sich nachher verhält, beim endladen. Das neue Skript ist noch "frisch".@Gismoh sagte in Venus V3.0 API Token:
Habe nun auch komplett umgeschwenkt auf die Api Steuerung.
Mit der neuen Firmware hatte ich zwar auch die Api Funktion in der App, aber der Speicher hatte nicht geantwortet.
Der Support hatte mir dann neuere Firmware freigeschaltet, und ja hat geklappt, die Speicher kann ich nun via API regeln.
Das Laden hatte via Skript schon mal geklappt, mal sehen, wie es sich nachher verhält, beim endladen. Das neue Skript ist noch "frisch".Kannst du deinen Stand hier aktuell halten? Mein Script ist überhaupt noch nicht ausgereift und mit meiner Shelly Emulation hab ich nur Probleme
-
@Gismoh sagte in Venus V3.0 API Token:
Habe nun auch komplett umgeschwenkt auf die Api Steuerung.
Mit der neuen Firmware hatte ich zwar auch die Api Funktion in der App, aber der Speicher hatte nicht geantwortet.
Der Support hatte mir dann neuere Firmware freigeschaltet, und ja hat geklappt, die Speicher kann ich nun via API regeln.
Das Laden hatte via Skript schon mal geklappt, mal sehen, wie es sich nachher verhält, beim endladen. Das neue Skript ist noch "frisch".Kannst du deinen Stand hier aktuell halten? Mein Script ist überhaupt noch nicht ausgereift und mit meiner Shelly Emulation hab ich nur Probleme
@Hansi1234 gerne.
Wie gesagt kann die steuern, das das Skript zwischen laden und entladen wechselt.
Aber das Timing stimmt aktuell nicht, bin gerade aktiv am testen und quasi am "debuggen". -
@Hansi1234 gerne.
Wie gesagt kann die steuern, das das Skript zwischen laden und entladen wechselt.
Aber das Timing stimmt aktuell nicht, bin gerade aktiv am testen und quasi am "debuggen".@Gismoh ja, Stichwort Hysterese. Aber gab's da nicht ein Adapter Nulleinspeisung oä?
Hast du es zufällig geschafft, den Akku via uni-meter zu betreiben? -
@Gismoh ja, Stichwort Hysterese. Aber gab's da nicht ein Adapter Nulleinspeisung oä?
Hast du es zufällig geschafft, den Akku via uni-meter zu betreiben?@Hansi1234 ne, unimeter habe ich ja gar nicht versucht. Wollte es ja ohne zusätzlichen Code machen, bei mir war ja alles nur im IOBroker als JS. Hatte dort die Regelung nicht hinbekommen, steuern konnte ich ja.
Hatte dies nun komplett verworfen und habe gestern mit der Steuerung über Api angefangen.
Ein Adapter "Nulleinspeisung" kenne ich nicht. -
@Gismoh ja, Stichwort Hysterese. Aber gab's da nicht ein Adapter Nulleinspeisung oä?
Hast du es zufällig geschafft, den Akku via uni-meter zu betreiben?@Hansi1234 habe das Regelskript mal sehr verkürzt und viel Funktionen rausgenommen (von ca. 1300 Zeilen auf ca. 200) und teste dies gerade.
Neuberechnung auch nur 1x je Minute.
Sieht bisher sauber aus, evtl. wollte ich auch direkt zu viel auf einmal.Dies ist mein aktuelles kleines Testscript: (aktuell nur für das endladen)
Aber nur für Testzwecke, denn es sind keine Fallbacks etc. eingebaut - lasse ich gerade auch nur unter Aufsicht laufen)// ============================================================ // MARSTEK_3 Hauptskript // v1.0.0 // // Datenpfad: 0_userdata.0.Akku_PV.Marstek_3. // // Logik: // - Jede Minute: Tibber lesen // - Formel: plug_real + tibber = neues Ziel // - 50/50 auf beide Speicher // - Keine Suppression, keine Verteilung, keine Sonderfaelle // ============================================================ const dgram = require('dgram'); const DP = '0_userdata.0.Akku_PV.Marstek_3.'; const TIBBER = 'tibberlink.0.LocalPulse.0.Power'; const PLUG_28 = 'shelly.1.shellyplugsg3#3528#1.Relay0.Power'; const PLUG_29 = 'shelly.1.shellyplugsg3#3529#1.Relay0.Power'; const IP_28 = '192.168.145.179'; const IP_29 = '192.168.145.155'; const PORT = 30000; const INTERVALL_MS = 60000; // 1 Minute const MAX_W = 800; // Hartgrenze pro Speicher const MIN_W = 50; // unter MIN_W -> 0W senden const EV_W = 10; // Eigenverbrauch Speicher (Elektronik) let udpClient = null; let ivMain = null; // ------------------------------------------------------------ // Datenpunkte anlegen // ------------------------------------------------------------ function initDP() { createState(DP + 'einstellungen.aktiv', true, { name: 'Steuerung aktiv', type: 'boolean', read: true, write: true }); createState(DP + 'einstellungen.max_w_pro_speicher', MAX_W, { name: 'Max W pro Speicher', type: 'number', unit: 'W', read: true, write: true }); createState(DP + 'einstellungen.min_w', MIN_W, { name: 'Min W (unter diesem Wert -> 0W)', type: 'number', unit: 'W', read: true, write: true }); createState(DP + 'status.tibber_w', 0, { name: 'Tibber aktuell', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.plug_28_w', 0, { name: 'Plug 3528', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.plug_29_w', 0, { name: 'Plug 3529', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.ziel_gesamt_w', 0, { name: 'Ziel gesamt', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.gesendet_28_w', 0, { name: 'Gesendet 3528', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.gesendet_29_w', 0, { name: 'Gesendet 3529', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.letzte_regelung', '', { name: 'Letzte Regelung', type: 'string', read: true, write: false }); } // ------------------------------------------------------------ // UDP // ------------------------------------------------------------ function initUDP() { udpClient = dgram.createSocket('udp4'); udpClient.on('error', function(e) { log('UDP Fehler: ' + e.message, 'warn'); }); udpClient.bind(30002, function() { log('✅ UDP bereit (Port 30002)'); }); } function sendManual(ip, watt) { if (!udpClient) return; const power = Math.round(watt); // positiv = entladen, negativ = laden const msg = JSON.stringify({ id: 1, method: 'ES.SetMode', params: { id: 0, config: { mode: 'Manual', manual_cfg: { time_num: 1, start_time: '00:00:00', end_time: '23:59:59', week_set: 127, power: power, enable: 1 } }} }); udpClient.send(Buffer.from(msg), PORT, ip, function(err) { if (err) log('UDP Send Fehler (' + ip + '): ' + err.message, 'warn'); }); } // ------------------------------------------------------------ // Hilfsfunktionen // ------------------------------------------------------------ function safeVal(path, fallback) { try { const s = getState(path); if (!s || s.val === null || s.val === undefined) return fallback; const n = parseFloat(s.val); return isNaN(n) ? fallback : n; } catch(e) { return fallback; } } function safeBool(path, fallback) { try { const s = getState(path); if (!s || s.val === null) return fallback; return !!s.val; } catch(e) { return fallback; } } // ------------------------------------------------------------ // Hauptregelung // ------------------------------------------------------------ function regeln() { if (!safeBool(DP + 'einstellungen.aktiv', true)) { log('⏸️ Steuerung deaktiviert'); return; } const maxW = safeVal(DP + 'einstellungen.max_w_pro_speicher', MAX_W); const minW = safeVal(DP + 'einstellungen.min_w', MIN_W); // Werte lesen const tibber = safeVal(TIBBER, 0); const plug28 = safeVal(PLUG_28, 0); const plug29 = safeVal(PLUG_29, 0); const plugGes = plug28 + plug29; // Diagnose-Datenpunkte setState(DP + 'status.tibber_w', Math.round(tibber)); setState(DP + 'status.plug_28_w', Math.round(plug28)); setState(DP + 'status.plug_29_w', Math.round(plug29)); // Real entladene Leistung (negativ = Entladen beim Shelly Plug) const realEntladen = plugGes < -EV_W ? Math.abs(plugGes) : 0; // Tempomat-Formel let zielGesamt = realEntladen + tibber; zielGesamt = Math.max(0, zielGesamt); setState(DP + 'status.ziel_gesamt_w', Math.round(zielGesamt)); // Unter Minimum -> Standby if (zielGesamt < minW) { log('⏸️ Standby: Ziel ' + Math.round(zielGesamt) + 'W < Min ' + minW + 'W'); sendManual(IP_28, 0); sendManual(IP_29, 0); setState(DP + 'status.gesendet_28_w', 0); setState(DP + 'status.gesendet_29_w', 0); setState(DP + 'status.letzte_regelung', new Date().toLocaleTimeString() + ' | Standby'); return; } // 50/50 aufteilen, begrenzen let w28 = Math.min(Math.round(zielGesamt / 2), maxW); let w29 = Math.min(Math.round(zielGesamt / 2), maxW); // Senden sendManual(IP_28, w28); sendManual(IP_29, w29); setState(DP + 'status.gesendet_28_w', w28); setState(DP + 'status.gesendet_29_w', w29); const ts = new Date().toLocaleTimeString(); const info = ts + ' | Tibber: ' + Math.round(tibber) + 'W' + ' | Plug: ' + Math.round(plugGes) + 'W' + ' | Ziel: ' + Math.round(zielGesamt) + 'W' + ' | 3528: ' + w28 + 'W | 3529: ' + w29 + 'W'; setState(DP + 'status.letzte_regelung', info); log('📤 ' + info); } // ------------------------------------------------------------ // Start / Stop // ------------------------------------------------------------ function start() { log('🚀 MARSTEK_3 Hauptskript v1.0.0 gestartet'); initDP(); initUDP(); setTimeout(function() { regeln(); // sofort einmal ivMain = setInterval(regeln, INTERVALL_MS); log('✅ Regelintervall: 60s'); }, 2000); } start(); onStop(function() { if (ivMain) { clearInterval(ivMain); } if (udpClient) { sendManual(IP_28, 0); sendManual(IP_29, 0); setTimeout(function() { try { udpClient.close(); } catch(e) {} }, 500); } log('🛑 MARSTEK_3 gestoppt - 0W gesendet'); }, 1500); -
@Hansi1234 habe das Regelskript mal sehr verkürzt und viel Funktionen rausgenommen (von ca. 1300 Zeilen auf ca. 200) und teste dies gerade.
Neuberechnung auch nur 1x je Minute.
Sieht bisher sauber aus, evtl. wollte ich auch direkt zu viel auf einmal.Dies ist mein aktuelles kleines Testscript: (aktuell nur für das endladen)
Aber nur für Testzwecke, denn es sind keine Fallbacks etc. eingebaut - lasse ich gerade auch nur unter Aufsicht laufen)// ============================================================ // MARSTEK_3 Hauptskript // v1.0.0 // // Datenpfad: 0_userdata.0.Akku_PV.Marstek_3. // // Logik: // - Jede Minute: Tibber lesen // - Formel: plug_real + tibber = neues Ziel // - 50/50 auf beide Speicher // - Keine Suppression, keine Verteilung, keine Sonderfaelle // ============================================================ const dgram = require('dgram'); const DP = '0_userdata.0.Akku_PV.Marstek_3.'; const TIBBER = 'tibberlink.0.LocalPulse.0.Power'; const PLUG_28 = 'shelly.1.shellyplugsg3#3528#1.Relay0.Power'; const PLUG_29 = 'shelly.1.shellyplugsg3#3529#1.Relay0.Power'; const IP_28 = '192.168.145.179'; const IP_29 = '192.168.145.155'; const PORT = 30000; const INTERVALL_MS = 60000; // 1 Minute const MAX_W = 800; // Hartgrenze pro Speicher const MIN_W = 50; // unter MIN_W -> 0W senden const EV_W = 10; // Eigenverbrauch Speicher (Elektronik) let udpClient = null; let ivMain = null; // ------------------------------------------------------------ // Datenpunkte anlegen // ------------------------------------------------------------ function initDP() { createState(DP + 'einstellungen.aktiv', true, { name: 'Steuerung aktiv', type: 'boolean', read: true, write: true }); createState(DP + 'einstellungen.max_w_pro_speicher', MAX_W, { name: 'Max W pro Speicher', type: 'number', unit: 'W', read: true, write: true }); createState(DP + 'einstellungen.min_w', MIN_W, { name: 'Min W (unter diesem Wert -> 0W)', type: 'number', unit: 'W', read: true, write: true }); createState(DP + 'status.tibber_w', 0, { name: 'Tibber aktuell', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.plug_28_w', 0, { name: 'Plug 3528', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.plug_29_w', 0, { name: 'Plug 3529', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.ziel_gesamt_w', 0, { name: 'Ziel gesamt', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.gesendet_28_w', 0, { name: 'Gesendet 3528', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.gesendet_29_w', 0, { name: 'Gesendet 3529', type: 'number', unit: 'W', read: true, write: false }); createState(DP + 'status.letzte_regelung', '', { name: 'Letzte Regelung', type: 'string', read: true, write: false }); } // ------------------------------------------------------------ // UDP // ------------------------------------------------------------ function initUDP() { udpClient = dgram.createSocket('udp4'); udpClient.on('error', function(e) { log('UDP Fehler: ' + e.message, 'warn'); }); udpClient.bind(30002, function() { log('✅ UDP bereit (Port 30002)'); }); } function sendManual(ip, watt) { if (!udpClient) return; const power = Math.round(watt); // positiv = entladen, negativ = laden const msg = JSON.stringify({ id: 1, method: 'ES.SetMode', params: { id: 0, config: { mode: 'Manual', manual_cfg: { time_num: 1, start_time: '00:00:00', end_time: '23:59:59', week_set: 127, power: power, enable: 1 } }} }); udpClient.send(Buffer.from(msg), PORT, ip, function(err) { if (err) log('UDP Send Fehler (' + ip + '): ' + err.message, 'warn'); }); } // ------------------------------------------------------------ // Hilfsfunktionen // ------------------------------------------------------------ function safeVal(path, fallback) { try { const s = getState(path); if (!s || s.val === null || s.val === undefined) return fallback; const n = parseFloat(s.val); return isNaN(n) ? fallback : n; } catch(e) { return fallback; } } function safeBool(path, fallback) { try { const s = getState(path); if (!s || s.val === null) return fallback; return !!s.val; } catch(e) { return fallback; } } // ------------------------------------------------------------ // Hauptregelung // ------------------------------------------------------------ function regeln() { if (!safeBool(DP + 'einstellungen.aktiv', true)) { log('⏸️ Steuerung deaktiviert'); return; } const maxW = safeVal(DP + 'einstellungen.max_w_pro_speicher', MAX_W); const minW = safeVal(DP + 'einstellungen.min_w', MIN_W); // Werte lesen const tibber = safeVal(TIBBER, 0); const plug28 = safeVal(PLUG_28, 0); const plug29 = safeVal(PLUG_29, 0); const plugGes = plug28 + plug29; // Diagnose-Datenpunkte setState(DP + 'status.tibber_w', Math.round(tibber)); setState(DP + 'status.plug_28_w', Math.round(plug28)); setState(DP + 'status.plug_29_w', Math.round(plug29)); // Real entladene Leistung (negativ = Entladen beim Shelly Plug) const realEntladen = plugGes < -EV_W ? Math.abs(plugGes) : 0; // Tempomat-Formel let zielGesamt = realEntladen + tibber; zielGesamt = Math.max(0, zielGesamt); setState(DP + 'status.ziel_gesamt_w', Math.round(zielGesamt)); // Unter Minimum -> Standby if (zielGesamt < minW) { log('⏸️ Standby: Ziel ' + Math.round(zielGesamt) + 'W < Min ' + minW + 'W'); sendManual(IP_28, 0); sendManual(IP_29, 0); setState(DP + 'status.gesendet_28_w', 0); setState(DP + 'status.gesendet_29_w', 0); setState(DP + 'status.letzte_regelung', new Date().toLocaleTimeString() + ' | Standby'); return; } // 50/50 aufteilen, begrenzen let w28 = Math.min(Math.round(zielGesamt / 2), maxW); let w29 = Math.min(Math.round(zielGesamt / 2), maxW); // Senden sendManual(IP_28, w28); sendManual(IP_29, w29); setState(DP + 'status.gesendet_28_w', w28); setState(DP + 'status.gesendet_29_w', w29); const ts = new Date().toLocaleTimeString(); const info = ts + ' | Tibber: ' + Math.round(tibber) + 'W' + ' | Plug: ' + Math.round(plugGes) + 'W' + ' | Ziel: ' + Math.round(zielGesamt) + 'W' + ' | 3528: ' + w28 + 'W | 3529: ' + w29 + 'W'; setState(DP + 'status.letzte_regelung', info); log('📤 ' + info); } // ------------------------------------------------------------ // Start / Stop // ------------------------------------------------------------ function start() { log('🚀 MARSTEK_3 Hauptskript v1.0.0 gestartet'); initDP(); initUDP(); setTimeout(function() { regeln(); // sofort einmal ivMain = setInterval(regeln, INTERVALL_MS); log('✅ Regelintervall: 60s'); }, 2000); } start(); onStop(function() { if (ivMain) { clearInterval(ivMain); } if (udpClient) { sendManual(IP_28, 0); sendManual(IP_29, 0); setTimeout(function() { try { udpClient.close(); } catch(e) {} }, 500); } log('🛑 MARSTEK_3 gestoppt - 0W gesendet'); }, 1500);@Gismoh heißt du lädst immer manuell auf, wenn du Überschuss hast
-
@Hansi1234 Nein, natürlich nicht.
Hatte doch geschrieben, das es nur ein sehr kurzes Testskript war (um Fehlerquellen- auszuschließen). Mein vorherigen Code war x mal so lange und hatte sehr viel mehr features drin.Aber gestern Abend ging es für mich "back to the roots" und nach 21 Uhr gab es eben keine Sonne ;)
Hatte es noch ein wenig erweitert, so das ich es habe laufen lassen, und nun bin ich gerade aufgewacht, und es hat bereits geladen, bis Pmax. je Speicher.
Und es hat unseren, obwohl sehr einfach geschrieben, Zukauf von Strom, heute bislang auf 60 Watt begrenzt.