NEWS
Hoymiles WR mit 1600W regeln
-
Guten Abend miteinander,
ich habe folgendes Setup:
mME --> Einspeisung WR auf L1 --> ShellyEM 3 --> Verbraucher
Dieser Aufbau ist den Gegebenheiten geschuldet.
Ich schreibe meine Daten mittels des Shelly-Adapter in iobroker und mqtt mit. Die Daten des WR liefert mir eine OpenDTU - diese soll auch die neue Leistungsgrenze schreiben.
Ich habe folgenden JavaScript-Code erarbeitet:
// Datenpunkte const wrPowerDP = 'opendtu.0.1164a00f8949.ac.phase_1.power'; // Wechselrichter-Leistung const housePowerDP = 'shelly.0.SHEM-3#485519C98888#1.Total.InstantPower'; // Hausverbrauch const mqttLimitDP = 'opendtu.0.1164a00f8949.power_control.limit_nonpersistent_absolute'; // MQTT Limit-Datenpunkt const producingDP = 'opendtu.0.1164a00f8949.producing'; // Producing Status // Konfiguration const thresholdWR = 800; // Mindestleistung des Wechselrichters in Watt const thresholdDifferenceMin = 400; // Mindestdifferenz für das Setzen eines Limits const thresholdDifferenceMax = 50; // Maximale Differenz, um das Limit zu erhöhen const maxWRPower = 1600; // Maximale zulässige Leistung des WR const changeThreshold = 10; // Schwellenwert für signifikante Limitänderung (in Watt) // Initialisiere Zähler-Datenpunkte für Prüfungen und Limitänderungen if (!existsState('0_userdata.0.solar.check_counter')) { createState('0_userdata.0.solar.check_counter', 0, { name: 'Anzahl der Prüfungen', type: 'number', unit: 'Prüfungen', read: true, write: true }); } if (!existsState('0_userdata.0.solar.change_counter')) { createState('0_userdata.0.solar.change_counter', 0, { name: 'Anzahl der Prüfungen mit Limitänderung', type: 'number', unit: 'Prüfungen', read: true, write: true }); } if (!existsState('0_userdata.0.solar.no_change_counter')) { createState('0_userdata.0.solar.no_change_counter', 0, { name: 'Anzahl der Prüfungen ohne Limitänderung', type: 'number', unit: 'Prüfungen', read: true, write: true }); } // Differenz-Datenpunkt für Grafana if (!existsState('0_userdata.0.solar.wr_haus_difference')) { createState('0_userdata.0.solar.wr_haus_difference', 0, { name: 'WR - Haus Leistung Differenz', type: 'number', unit: 'Watt', read: true, write: true }); } // Zustand für Low Power Mode if (!existsState('0_userdata.0.solar.low_power_mode')) { createState('0_userdata.0.solar.low_power_mode', false, { name: 'Low Power Mode aktiv', type: 'boolean', read: true, write: true }); } // Funktion zur Berechnung des Limits function calculateLimit(wrPower, housePower) { let limit = wrPower - thresholdDifferenceMin; if (wrPower - housePower < thresholdDifferenceMax || wrPower - housePower > thresholdDifferenceMin) { limit = housePower + thresholdDifferenceMin; } if (limit < 0) { limit = 0; } else if (limit > maxWRPower) { limit = maxWRPower; } return limit; } // Hauptfunktion zur Leistungsprüfung und Limitsteuerung function checkPower() { const wrPower = getState(wrPowerDP).val; const housePower = getState(housePowerDP).val; const powerDifference = parseFloat((wrPower - housePower).toFixed(2)); const isLowPower = getState('0_userdata.0.solar.low_power_mode').val; const currentLimit = getState(mqttLimitDP).val; // Prüfungszähler erhöhen let checkCount = getState('0_userdata.0.solar.check_counter').val + 1; setState('0_userdata.0.solar.check_counter', checkCount); // WR-Leistung unter Schwellwert → Low Power Mode if (wrPower < thresholdWR) { if (!isLowPower) { console.log('WR-Leistung unter ' + thresholdWR + ' W – Low Power Mode aktiviert'); console.log('Limit wird geändert von ' + currentLimit + ' W auf ' + maxWRPower + ' W'); setState(mqttLimitDP, maxWRPower); setState('0_userdata.0.solar.low_power_mode', true); let changeCount = getState('0_userdata.0.solar.change_counter').val + 1; setState('0_userdata.0.solar.change_counter', changeCount); } else { console.log('Low Power Mode aktiv – WR-Leistung weiter unter ' + thresholdWR + ' W'); console.log('Limit bleibt unverändert bei ' + currentLimit + ' W'); let noChangeCount = getState('0_userdata.0.solar.no_change_counter').val + 1; setState('0_userdata.0.solar.no_change_counter', noChangeCount); } } else { if (isLowPower) { console.log('WR-Leistung über ' + thresholdWR + ' W – Low Power Mode deaktiviert'); setState('0_userdata.0.solar.low_power_mode', false); } if (powerDifference >= 0) { const newLimit = calculateLimit(wrPower, housePower); if (Math.abs(currentLimit - newLimit) >= changeThreshold) { console.log('Limit wird geändert von ' + currentLimit + ' W auf ' + newLimit + ' W'); setState(mqttLimitDP, newLimit); let changeCount = getState('0_userdata.0.solar.change_counter').val + 1; setState('0_userdata.0.solar.change_counter', changeCount); } else { console.log('Limit bleibt unverändert bei ' + currentLimit + ' W – Änderung (' + Math.abs(currentLimit - newLimit) + ' W) unterhalb Schwelle (' + changeThreshold + ' W)'); let noChangeCount = getState('0_userdata.0.solar.no_change_counter').val + 1; setState('0_userdata.0.solar.no_change_counter', noChangeCount); } } else { console.log('Keine Regelung – WR-Haus Differenz negativ (' + powerDifference + ' W)'); } } setState('0_userdata.0.solar.wr_haus_difference', powerDifference); } // Sofort prüfen bei Produktionsstart on({ id: producingDP, val: true }, function () { console.log('Produktion gestartet – Starte erste Prüfung der Leistung'); checkPower(); }); // Zyklische Prüfung alle 15 Sekunden bei aktiver Produktion setInterval(function () { if (getState(producingDP).val === true) { checkPower(); } }, 60000);
Ich möchte die Anzahl der Schreibvorgänge auf den WR so gering wie möglich halten, daher die eingebauten Einschränkungen.
Allerdings klappt das schreiben des neuen Limit auf den WR nicht - habe ich irgendwo einen Denkfehler?
Gruß, NobbyNobs