NEWS
E3DC -mit RSCp Adapter - Batterielaufzeiten und RestSOC
-
Hi,
hab mal ein Script geschrieben. Ihr müsstet ganz oben Eure Batteriekapazität nur ändern, der Rest sollte out of the box laufen, da ich auf den e3dc rscp-adapter zugreife. Und bitte noch Eure 3 Datenpunkte anlegen.0_userdata.0.e3dc.Berechnungen.Batterie.Sonnuntergang_Sonnenaufgang_SOC - wie ist der Soc beim Sonnenaufgang (nur beim Entladen) und beim Sonnenuntergang (nur beim Laden) - z.b. 36%
0_userdata.0.e3dc.Berechnungen.Batterie.Uhrzeit_100_oder_0 - zu welcher Uhrzeit ist der Batteriestand 0 oder 100 - 0 nur beim Entladen, 100 nur beim Laden der Batterie
0_userdata.0.e3dc.Berechnungen.Batterie.Zeit_bis_100_oder_0 - wie lange dauert es bis die Batterie bei der derzeitigen Lade/Entladeleistung der Batterie bei 0 oder 100 ist.So könnte das dann aussehen:
Da kann man sicher noch eine Menge Sachen mache.
Aber für die einfachen Anzeigen sollte das halbwegs stimmen. Ist auch mehr eine Orientierung, also Leistungsaufnahmebegrenzung mit Faktoren sind nicht drin//update 08/03/24 08:39 on({ id: [].concat(['e3dc-rscp.0.EMS.POWER_BAT']).concat(['e3dc-rscp.0.EMS.POWER_HOME']), change: 'ne' }, async (obj) => { // Gegebene Werte var batterieKapazitaetWh = 19580; // Kapazität der Batterie in Wattstunden var aktuelleLeistungWatt = getState("e3dc-rscp.0.EMS.POWER_BAT").val; // Aktuelle Ladeleistung in Watt (positiv für das Laden, negativ für das Entladen) //var nennspannungBatterieV = 44.5; // Nennspannung der Batterie in Volt var aktuellerSoc = getState("e3dc-rscp.0.EMS.BAT_SOC").val; // Aktueller State of Charge (SoC) in Prozent var sonnenaufgang = getState("0_userdata.0.Astrozeiten.sunrise").val; // Zeitpunkt des Sonnenaufgangs (z.B. "06:13") var sonnenuntergang = getState("0_userdata.0.Astrozeiten.sunset").val; // Zeitpunkt des Sonnenuntergangs (z.B. "17:58") // wenn Soc 0, um Division durch 0 zu vermeiden if (aktuellerSoc>0) { var restKapazitaet_laden=batterieKapazitaetWh-((aktuellerSoc/100) * batterieKapazitaetWh); } else { var restKapazitaet_laden=batterieKapazitaetWh; } var restKapazitaet_entladen=((aktuellerSoc/100) * batterieKapazitaetWh); //Datenpunkte müsst ihr von Hand anlegen, wenn ihr die braucht const Soc_Zeitpunkt="0_userdata.0.e3dc.Berechnungen.Batterie.Sonnuntergang_Sonnenaufgang_SOC"; const Uhrzeit_0_100="0_userdata.0.e3dc.Berechnungen.Batterie.Uhrzeit_100_oder_0"; const Zeitpunkt_bis="0_userdata.0.e3dc.Berechnungen.Batterie.Zeit_bis_100_oder_0"; var ladungsdauerStunden=""; // Umwandlung der Uhrzeit in ein gültiges Datum var heute = new Date(); var [stunden, minuten] = sonnenuntergang.split(":"); var sonnenuntergang_Datum = new Date(heute.getFullYear(), heute.getMonth(), heute.getDate(), stunden, minuten); var [stunden_a, minuten_a] = sonnenaufgang.split(":"); var sonnenaufgang_Datum = new Date(heute.getFullYear(), heute.getMonth(), heute.getDate(), stunden_a, minuten_a); var Zeit_bis_Sonnenuntergang=(sonnenuntergang_Datum.getTime() - heute.getTime()) / (3600 * 1000); var Zeit_bis_Sonnenaufgang=(sonnenaufgang_Datum.getTime() - heute.getTime()) / (3600 * 1000); // Einen Tag in Millisekunden const einTagInStunden = 24; if (Zeit_bis_Sonnenuntergang<0) { Zeit_bis_Sonnenuntergang=Zeit_bis_Sonnenuntergang+einTagInStunden; } if (Zeit_bis_Sonnenaufgang<0) { Zeit_bis_Sonnenaufgang=Zeit_bis_Sonnenaufgang+einTagInStunden; } console.log ("*** Info *****") console.log ("Restkapazität_laden: " +restKapazitaet_laden); console.log("Aktuelle Leistung: " + aktuelleLeistungWatt); console.log ("Leistung / h:" + restKapazitaet_laden/aktuelleLeistungWatt); console.log ("*** /Info *****"); // ############################ Ausgabe Laden #############################################################Aus if (aktuelleLeistungWatt > 0) { ladungsdauerStunden = Math.abs(restKapazitaet_laden / aktuelleLeistungWatt); setState(Zeitpunkt_bis,dezimaleStundenInStundenUndMinuten(ladungsdauerStunden)); console.log(`**Batterieladung:**`); console.log("- Restladezeit bis 100%: "+ladungsdauerStunden+" Stunden"); console.log("Zeit bis Sonnenuntergang: " +(sonnenuntergang_Datum.getTime() - heute.getTime()) / (3600 * 1000)) console.log("Ladungsdauer Stunden:" +ladungsdauerStunden) // Zeitpunkt 100% SoC berechnen, wenn vor Sonnenuntergang 100% erreicht if (ladungsdauerStunden <= Zeit_bis_Sonnenaufgang) { var zeitpunkt100Prozent = new Date().getTime() + (ladungsdauerStunden * 3600 * 1000); console.log(`- Zeitpunkt 100% SoC: ${new Date(zeitpunkt100Prozent).toLocaleString()}`); setState(Uhrzeit_0_100,new Date(zeitpunkt100Prozent).toLocaleString()); setState(Soc_Zeitpunkt,"100"); } else{ // SoC bei Sonnenuntergang berechnen var socSonnenuntergang = aktuellerSoc + ((Zeit_bis_Sonnenuntergang*aktuelleLeistungWatt))*100/19500; console.log(`- Stand des SoC beim Sonnenuntergang: ${socSonnenuntergang.toFixed(2)}%` + " Leistung: "+Zeit_bis_Sonnenuntergang*aktuelleLeistungWatt+" Restkapazität: " + restKapazitaet_laden ); setState(Soc_Zeitpunkt,socSonnenuntergang.toFixed(2)); } } // ###################################Entladen########################################################################################## else if (aktuelleLeistungWatt < 0) { console.log ("Restkapazität: " +restKapazitaet_entladen); console.log ("Leistung / h:" + restKapazitaet_entladen/aktuelleLeistungWatt); ladungsdauerStunden = Math.abs(restKapazitaet_entladen / aktuelleLeistungWatt*-1); setState(Zeitpunkt_bis,dezimaleStundenInStundenUndMinuten(ladungsdauerStunden)); var zeitpunkt0Prozent = new Date().getTime() + (ladungsdauerStunden * 3600 * 1000); // Ausgabe für Entladen console.log(`**Batterieentladung:*`); console.log(`- Restentladezeit bis 0%: ${ladungsdauerStunden} Stunden`); console.log("Zeit bis Sonnenaufgang" + Zeit_bis_Sonnenaufgang) // Zeitpunkt 0% SoC berechnen if (ladungsdauerStunden <= Zeit_bis_Sonnenaufgang) { console.log(`- Zeitpunkt 0% SoC: ${new Date(zeitpunkt0Prozent).toLocaleString()}`); setState(Uhrzeit_0_100,new Date(zeitpunkt0Prozent).toLocaleString()); setState(Soc_Zeitpunkt,"0"); } else{ // SoC bei Sonnenaufgang berechnen var socSonnenaufgang = (aktuellerSoc - (Zeit_bis_Sonnenaufgang*aktuelleLeistungWatt))*100/19500; console.log(`- Stand des SoC beim Sonnenaufgang: ${socSonnenaufgang.toFixed(2)}%` + " Leistung: "+Zeit_bis_Sonnenaufgang*aktuelleLeistungWatt); if (socSonnenaufgang>=0) { setState(Soc_Zeitpunkt,socSonnenaufgang.toFixed(2)); setState(Uhrzeit_0_100,new Date(zeitpunkt0Prozent).toLocaleString()); } else { setState(Soc_Zeitpunkt,"0"); } } } else { console.log("Die Batterie hat aktuell keine Ladeleistung."); setState(Soc_Zeitpunkt,aktuellerSoc); setState(Uhrzeit_0_100,"--:--h"); setState(Zeitpunkt_bis,"Batterie lädt nicht") } });
Diese Funktion müsst ihr noch irgendwo einbinden, steht bei mir in den globalen Scripten, damit die Ladungsdauer in Stunden und Minuten ausgegeben wird.
function dezimaleStundenInStundenUndMinuten(dezimaleStunden) { // Berechne die Gesamtzahl der Minuten const gesamtMinuten = dezimaleStunden * 60; // Extrahiere die Stunden (Ganzzahlanteil) const stunden = Math.floor(dezimaleStunden); // Extrahiere die Minuten (Nachkommateil) const minuten = Math.round((dezimaleStunden - stunden) * 60); // Füge führende Nullen hinzu const stundenMitNullen = stunden < 10 ? `0${stunden}` : stunden; const minutenMitNullen = minuten < 10 ? `0${minuten}` : minuten; return `${stundenMitNullen}:${minutenMitNullen}h`; }
und dieses Script muss auch laufen, damit die Sonnenaufgänge und Untergänge angezeigt werden. Das habe ich hier aus dem Forum, finde es jetzt aber nicht mehr, falls jemand einen Link hat würde ich das gern ergänzen.
// v0.2 const suncalc = require('suncalc2'); const prefix = '0_userdata.0'; function fillAstroStates() { try { const systemConfig = getObject('system.config'); // console.log(`Starting fillAstroStates with latitude: ${systemConfig.common.latitude} and longitude: ${systemConfig.common.longitude}`); const times = suncalc.getTimes(new Date(), systemConfig.common.latitude, systemConfig.common.longitude); for (var t in times) { const h = times[t].getHours(); const m = times[t].getMinutes(); const timeFormatted = `${h < 10 ? '0' + h : h}:${m < 10 ? '0' + m : m}`; const objId = `${prefix}.Astrozeiten.${t}`; if (!existsObject(objId)) { createState(objId, timeFormatted, { name: `Astro ${t}`, type: 'string', role: 'value' }); } else { setState(objId, { val: timeFormatted, ack: true }); } } } catch (err) { console.error(err); } } // Refresh every day at 00:01 schedule('1 0 * * *', fillAstroStates); // Run immediately after script start fillAstroStates();
Bei Fragen einfach fragen.
Gruß Tom -
@tomtom24 so, sollte jetzt passen, jedenfalls bei mir, hab noch ein paar Datenpunkte hinzugefügt, die müsst ihr dann selber anlegen, bin faul
Ich füge bei den Scripten immer oben in der ersten Zeile das Datum für das Update ein, so dass ihr selber schauen könnt, wann da Fehler rauskamen -
Sehr cool, vielen Dank!
Da mein RSCP noch rumzickt, hole ich jetzt die Werte per modbus (übrigens danke an @ArnoD und seinen Post von 2021. Die einzige Datei, die sich bei mir importieren ließ!)
Aber hier kann ich die Kapazität in % auch in einem Datenpunkt berechnen, oder?
Hätte gerne noch einen Punkt "Batterie wird geladen - true/false".EDIT: Jetzt mal ne ganz blöde Frage: bei einer angenommenen Kapazität der Batterie von 5000 Wh und einem angezeigten Ladezustand von 1000 Wh müsste doch die SoC bei 20% sein. Es werden aber nur 10% angezeigt.
Liegt es daran, dass sich das Vorzeichen bei Ladung/Entladung ändert und deshalb die Range nicht von 0 bis 5000 Wh geht sondern von -5000 bis +5000???
Welcher Wert stimmt denn jetzt, welchen nehme ich für meine VIS?Ich bin verwirrt!