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);