NEWS
Zwangsladung mit Sungrow SH10RT
-
Hallo zusammen,
ich möchte euch gerne meine Scripte zeigen und mir natürlich Tips abholen, was man verbessern kann. In einem Script steckt noch ein kleinrr Fehler, wobei ich noch Hilfe brauche.
Grundsätzlich sind es drei Scripte die zusammenarbeiten.Beschreibung:
Im Grunde gehts um darum den Batteriespeicher meiner PV Anlage zu bestimmten Zeiten voll zu laden.
Ich nutze einen dynamischen Stromtarif. Da macht es Sinn, wenn keine Sonne zu erwarten ist, den Speicher zu billligen Stromzeiten zu füllen und ihn dann in teuren Zeiten zu nutzen.Ich will keine vollautomatische Lösung. Zumindest noch nicht.
Wenn ich sehe das der Speicher recht leer ist und auf Grund der Witterung keine Speicherladung zu erwarten ist, will ich mit Hilfe von Telegram eine automatische Aufladung vormerken.
iobroker schaut dann, wann der billigste Strompreis ist und startet dann die Zwangsladung.- Script (Strompreise sortieren)
Über den Adapter Awattar kommen um 15 Uhr immer die Strompreise vom nächsten Tag rein.
Das Script schaut sich die Strompreise an und beschreibt anschließend drei Benutzervariablen:
0_userdata.0.Strompreis.billigster_Preis -> hier wird der billigste Preis rein kopiert
0_userdata.0.Strompreis.Zeitpunkt_Strom > hier der Zeitpunkt ab wann der billigste Preis gilt
0_userdata.0.Strompreis.Datum_Strom -> und hier an welchem Datum (zur Sicherheit)
Das Script ist komplett mit KI erstellt worden. Da habe ich keine Aktien drin.
Funktioniert aber:// Array für alle Preisdatenpunkte und Startzeit-Datenpunkte der Stunden 24 bis 47 const preisDatenpunkte = []; const startZeitDatenpunkte = []; const startDatumDatenpunkte = []; for (let i = 24; i < 48; i++) { preisDatenpunkte.push(`awattar.0.prices.${i}.nettoPriceKwh`); startZeitDatenpunkte.push(`awattar.0.prices.${i}.start`); startDatumDatenpunkte.push(`awattar.0.prices.${i}.startDate`); } // Funktion zum Finden des minimalen Preises und zugehöriger Startzeit und Datum function findeKleinstenPreis() { let minPreis = Number.MAX_VALUE; let zeitpunkt = null; let datum = null; preisDatenpunkte.forEach((preisDP, index) => { const preis = getState(preisDP).val; if (preis < minPreis) { minPreis = preis; zeitpunkt = getState(startZeitDatenpunkte[index]).val; datum = getState(startDatumDatenpunkte[index]).val; } }); setState('0_userdata.0.Strompreis.billigster_Preis', minPreis, true); setState('0_userdata.0.Strompreis.Zeitpunkt_Strom', zeitpunkt, true); setState('0_userdata.0.Strompreis.Datum_Strom', datum, true); // NEU: Datum speichern } // Überwache alle Preis-Datenpunkte auf Änderung preisDatenpunkte.forEach(dp => { on({ id: dp, change: 'ne' }, () => { findeKleinstenPreis(); }); }); // Initialer Aufruf beim Start des Skripts findeKleinstenPreis();
- Script (generelle Auslösung der Zwangsladung)
Dieses Script löst eine Zwangsladung aus, wenn die Variable 0_userdata.0.Netzladung.Ausloesebit_Netzladung wahr ist.
(In Telegram kann ich somit die Zwangsladung manuell aktivieren oder deaktivieren)
Wenn das o.g. Bit wahr ist, startet die Zwangsladung sofort.
Bei false stopt die Zwangsladung sofort und alles setzt sich zurück auf Standartwerte.
Außerdem wird das Bit zurückgesetzt, nachdem 30 Minuten geladen wurde oder der Speicher voll ist (100%)- Script die automatische Aufladung.
Dieses Script ist nur im Grundgerüst fertig, weil ich es noch am testen bin.
Aktuell sendet es nur Telegramnachrichten. Später soll anstatt eine Nachricht abzusenden, einfach nur das Netzladebit, welches im Script 2 den Auslöser definiert, auf wahr stellen.
Über Telegram wird ein Bit auf wahr gesetzt: 0_userdata.0.Netzladung.Ausloesebit_Netzladung_auto
Wenn das Bit wahr ist, wird das Netzladebit auf wahr gesteuert. Und zwar nur dann, wenn das Datum aus 0_userdata.0.Strompreis.Datum_Strom und der Zeitpunkt 0_userdata.0.Strompreis.Zeitpunkt_Strom passt.
Leider bekomme ich das mit dem Zeitpunkt nicht hin. Aktuell soll ja nur eine Nachricht auf Telegram gesendet werden. Das passiert noch nicht.
Aktuell habe ich noch einen Timeout drin. Auch zum testen.
Hier soll später das 0_userdata.0.Netzladung.Ausloesebit_Netzladung_auto Bit wieder zurückgesetzt werden.
Wann oder zu welchen Bedingungen muss ich mir noch überlegen.So, das wars erstmal.
Mich würde jetzt interessieren:
- Wo sind die Fehler, die ich gemacht habe oder was ließe sich verbessern?
- Wie bekomme ich in Script 3 die Auslösung mit dem Zeitpunkt hin?
- ne Idee, wann das Auto Bit sich wieder zurücksetzt? (Beim beenden der Zwangsladung? um Mitternancht?)
Gruß Helix
- Script (Strompreise sortieren)
-
@doppellhelix sagte: Wie bekomme ich in Script 3 die Auslösung mit dem Zeitpunkt hin?
-
@paul53
Hallo,erstmal vielen Dank für deine Arbeit.
Beeindruckend wie man auf sowas kommt.Ich habe gerade versucht das nachzubauen.
Kannst du mir den letzte Block einmal erklären?falls Wert von Objekt ID Automatik
mache KommentarWelche Objekt ID Automatik meinst du genau?
Ist das der Zeitpunkt, wenn ein neues Datum "reinkommt"?
und warum dann ein Kommentar?Gruß Helix
-
@doppellhelix sagte: Objekt ID Automatik
Das ist dein DP "Ausloesebit_Netzladung_auto".
@doppellhelix sagte in Zwangsladung mit Sungrow SH10RT:
warum dann ein Kommentar?
Anstelle des Kommentars füge dort die Aktion(en) ein, die zum Startzeitpunkt erfolgen sollen.
-
@paul53
Ok, habe ich gemacht.Leider bekomme ich dann diese Fehlermeldung:
javascript.0 15:53:55.645 error TypeError: Cannot read properties of undefined (reading 'toString') javascript.0 15:53:55.645 error at setStart (script.js.PV.Zwangsladung_Auto:8:35) javascript.0 15:53:55.645 error at script.js.PV.Zwangsladung_Auto:33:7 javascript.0 15:53:55.645 error at script.js.PV.Zwangsladung_Auto:40:3
Hast du eine Idee, was noch schief läuft?
-
@doppellhelix sagte: Idee, was noch schief läuft?
Was ich sehe, ist die falsche Variable für Stunden und Minuten. Richtig:
Die Prüfung von Datum und Uhrzeit ist unnötig, da nur zu diesem Zeitpunkt getriggert wird.
Das führt aber nicht zu der Fehlermeldung. Deshalb poste bitte den erzeugten Javascript-Code ohne die letzte Zeile in Code tags. -
Ich hoffe ich habe dich richtig verstanden:
var datum, uhrzeit, schedule1, timeout; // Beschreibe diese Funktion … async function setStart() { datum = getState('0_userdata.0.Strompreis.Datum_Strom').val.split(','); uhrzeit = getState('0_userdata.0.Strompreis.Zeitpunkt_Strom').val.split(':'); schedule1 = schedule((datum[1]).toString().trim() + ' ' + (datum[0]).toString().trim() + ' ' + (datum[0]).toString().trim() + ' ' + (datum[1]).toString().trim() + ' ' + '*'.toString().trim(), async () => { if (getState('0_userdata.0.Netzladung.Ausloesebit_Netzladung_auto').val) { if ((formatDate(new Date(), 'hh:mm:ss') == getState('0_userdata.0.Strompreis.Zeitpunkt_Strom').val) && (formatDate(new Date(), 'DD.MM.YYYY') == getState('0_userdata.0.Strompreis.Datum_Strom').val)) { sendTo('telegram', 'send', { text: 'Test automatisch Netzladen zum billigsten Zeitpunkt', }); } timeout = setTimeout(async () => { timeout = null; if (getState('0_userdata.0.Netzladung.Ausloesebit_Netzladung_auto').val == true) { setState('0_userdata.0.Netzladung.Ausloesebit_Netzladung_auto' /* Ausloesebit_Netzladung_auto */, false); sendTo('telegram', 'send', { text: 'Test automatisches Netzladungsbit beendet', }); } }, 300000); } }); } on({ id: [].concat(['0_userdata.0.Strompreis.Datum_Strom']).concat(['0_userdata.0.Strompreis.Zeitpunkt_Strom']), change: 'ne' }, async (obj) => { (() => { if (schedule1) { clearSchedule(schedule1); schedule1 = null; }})(); await setStart(); }); await setStart();
Vllt. noch zur Info:
die Variable 0_userdata.0.Strompreis.Datum_Strom hat das Format TT.MM.JJJJ
die Variable 0_userdata.0.Strompreis.Zeitpunkt_Strom hat das Format HH:MM:SS -
@doppellhelix sagte: die Variable 0_userdata.0.Strompreis.Datum_Strom hat das Format TT.MM.JJJJ
Deshalb muss der Punkt als Trennzeichen dienen - nicht das Komma.
Andere Fehler kann ich nicht erkennen. -
Vielen lieben Dank. Ich werde es testen.
Also zwei vermeidbare Fehler, die mir hätten auch auffallen können -
Hier noch der Vollständigkeitshalber das 3. Script.