Tibber Strompreise einlesen und Aktoren schalten

Allgemeines zur HomeMatic Haussteuerung

Moderator: Co-Administratoren

dovogt
Beiträge: 11
Registriert: 26.02.2021, 18:03
System: CCU
Hat sich bedankt: 2 Mal

Re: Tibber Strompreise einlesen und Aktoren schalten

Beitrag von dovogt » 28.02.2024, 08:26

Wie hast Du den Verbrauch vom Pulse direkt abgefragt?

TomTB
Beiträge: 77
Registriert: 18.11.2018, 15:30
System: CCU
Wohnort: Berlin
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: Tibber Strompreise einlesen und Aktoren schalten

Beitrag von TomTB » 29.02.2024, 08:41


dovogt
Beiträge: 11
Registriert: 26.02.2021, 18:03
System: CCU
Hat sich bedankt: 2 Mal

Re: Tibber Strompreise einlesen und Aktoren schalten

Beitrag von dovogt » 01.03.2024, 07:47

Ah, ok. Den hatte ich gesehen. Das ist ganz schön viel Aufwand, für den einen Wert. Ich hatte gehofft, dass es noch eine andere Möglichkeit gibt. :-(

Hast du den node.js Server auf dem raspi laufen, wo Die Homematic auch läuft? Du hast den Webserver auf der Bridge freigeschaltet. Wird dort die gleiche API bereitgestellt, wie über den tipper?
Würdest Du es nochmal genauer beschreiben, was Du gemacht hast und die Scripte zur Verfügung stellen?

TomTB
Beiträge: 77
Registriert: 18.11.2018, 15:30
System: CCU
Wohnort: Berlin
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: Tibber Strompreise einlesen und Aktoren schalten

Beitrag von TomTB » 01.03.2024, 08:56

Der Aufwand war überschaubar. Habe ich an einem Wochenende hinbekommen. Node läuft auf einem separaten Raspi, auf dem auch der CCU-Historian läuft. Scripte werde ich nicht teilen. Die sind auf meinen Anwendungsfall zugeschnitten und werfen wahrscheinlich viele Fragen auf.
Tom

dovogt
Beiträge: 11
Registriert: 26.02.2021, 18:03
System: CCU
Hat sich bedankt: 2 Mal

Re: Tibber Strompreise einlesen und Aktoren schalten

Beitrag von dovogt » 01.03.2024, 13:39

Ok. Ich versuche mich auch mal an einer Lösung.

TomTB
Beiträge: 77
Registriert: 18.11.2018, 15:30
System: CCU
Wohnort: Berlin
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: Tibber Strompreise einlesen und Aktoren schalten

Beitrag von TomTB » 04.03.2024, 08:49

Als Anregung:
Habe am Wochenende das Programm so erweitert, dass ich jetzt bei erkanntem Ladestart eine Nachricht aufs Smartphone (Telegram Bot) mit dem Zählerstand bekomme und bei Ladeende mit Zählerstand, Verbrauchsdifferenz und Kosten für den Ladevorgang.
Tom

Tyfys
Beiträge: 583
Registriert: 17.04.2021, 17:12
System: CCU
Hat sich bedankt: 29 Mal
Danksagung erhalten: 138 Mal

Re: Tibber Strompreise einlesen und Aktoren schalten

Beitrag von Tyfys » 05.03.2024, 13:10

mic4rd hat geschrieben:
04.01.2024, 20:03
Heute hatte ich endlich etwas Zeit und habe das Sortierskript von Tyfys integriert.
Da war noch ein kleiner Bug in der Sortierroutine.
Bei verschieden langen Elementen konnte es zu einer Verfälschung der Daten kommen,
wenn das kürzere Element mit dem Ende eines längeren Elementes übereinstimmte.

Der Fehler ist nun hier behoben.
Gruß
Harry

michaelapp
Beiträge: 280
Registriert: 16.05.2018, 22:54
Hat sich bedankt: 6 Mal
Danksagung erhalten: 5 Mal

Re: Tibber Strompreise einlesen und Aktoren schalten

Beitrag von michaelapp » 12.03.2024, 20:28

Hallo zusammen,

hab gerade die zwei Skripte eingebunden und es funktioniert hervorragend.

Bei der Systemvariable TIBBER_Strompreis_aktuell habe ich als Maßeinheit €/kWh hinterlegt, in der Anzeige sehe ich dann %u20AC/kWh

Bekomm ich das irgendwie korrekt angezeigt? Ansonsten hinterlege ich halt EUR/kWh

Gruß
Michael

mic4rd
Beiträge: 12
Registriert: 04.02.2023, 20:59
System: CCU
Hat sich bedankt: 6 Mal
Danksagung erhalten: 1 Mal

Re: Tibber Strompreise einlesen und Aktoren schalten

Beitrag von mic4rd » 05.06.2024, 17:31

Ich hatte vor einiger Zeit ein HmIP-WRCD angeschafft, um den aktuellen Strompreis und die Tendenz in der Küche direkt anzuzeigen.

Das Skript habe ich entsprechend erweitert, sodass es mittags schon die Preise für den Folgetag holt, diese um Mitternacht direkt übernimmt ohne weitere API-Abfrage. Hierzu braucht man dann 3 Skripte:

1. Strompreise um Mitternacht holen oder vom Vortag übernehmen

Code: Alles auswählen

! == Tibber-Strompreise Skript (Tägliche Ausführung um 0:00 Uhr) ==
! v1.4 (2024-02-21) Mic4rd
! Dank an MichaelN und Tyfys
! Quelle und Hinweise: https://homematic-forum.de/forum/viewtopic.php?f=19&t=79588&start=20#p787998

! Eingabe:
string apikey = "xxx"; ! Hier deinen persönlichen Tibber-API-Key eintragen
string cuxd = "CUxD.CUX2801001:1"; ! Hier dein CUXD-Device eintragen
string sysvar = "TIBBER_Strompreise"; ! Hier Namen der Systemvariablen (String) eintragen, in welche die Preise geschrieben werden sollen
string tmrvar = "TIBBER_Strompreise_morgen"; ! Hier die Systemvariable eintragen, in welcher die Preise von morgen sind
string errorvar = "TIBBER_API-Fehler"; ! Hier Namen der Systemvariablen (Bool) eintragen, welchen einen API-Fehler anzeigt
string inhibitvar = "TIBBER_Sperrzeiten"; ! Hier Namen der Systemvariablen (String) eintragen, in den die Sperrzeiten eingetragen werden
string inhibithrs = "TIBBER_Sperrstundenanzahl"; ! Hier Namen der Systemvariablen (Zahl) eintragen, in die die Anzahl der Sperrzeiten eingetragen wird
string inhibitprices = "TIBBER_Sperrzeitpreise"; ! Hier Namen der Systemvariablen (String) eintragen, in die die Preise der Sperrzeiten eingetragen wird
string inhibitmax = "TIBBER_Sperrstunden_max"; ! Hier Namen der Systemvariablen (Zahl) eintragen, in der die maximale Anzahl der Sperrstunden steht
string inhibitstring1 = "EXPENSIVE"; ! Preisniveau, ab dem gesperrt werden soll ("VERY_EXPENSIVE" oder "EXPENSIVE")
string inhibitstring2 = "NORMAL"; ! Soll zusätzlich auch bei NORMAL gesperrt werden ("NORMAL" oder "none" falls nicht benötigt)

! =================================
! Ausführung, ab hier nichts ändern
dom.GetObject(sysvar).State("error"); ! Wert auf error setzen, falls mit dem Abrufen etwas schiefgehen sollte
dom.GetObject(errorvar).State(1); ! Fehlervariable auf true setzen, falls mit dem Abrufen etwas schiefgehen sollte
string period = "today";
! Wenn Preise schon am Vortag geholt wurden, übernimm diese ohne weiteren API-Abruf
string tmr_prices = dom.GetObject(tmrvar).Value(); ! Preise vom Vortag 
if (tmr_prices.Contains("startsAt") && tmr_prices.Contains(system.Date("%F")) && tmr_prices.Length()>1500 ) {
  string tibber_prices = dom.GetObject(tmrvar).Value().Replace("tomorrow", "today");
  dom.GetObject(tmrvar).State("Erst ab ca. 13:30 Uhr verfügbar"); ! Preise von morgen leeren und mit Hinweis versehen
  WriteLine("Preise erfolgreich aus Zwischenspeicher übernommen!");
}
else {
  WriteLine("Preise aus API abrufen...");
  var tibberpriceurl="curl -H \"Authorization: Bearer "+apikey+"\" -H \"Content-Type: application/json\" -X POST -d  '{ \"query\": \"{viewer {homes {currentSubscription {priceInfo {"+period+" {startsAt total level}}}}}}\" }' https://api.tibber.com/v1-beta/gql"; ! Tibber API URL
  dom.GetObject(cuxd+".CMD_SETS").State(tibberpriceurl); ! Query-Ziel setzen
  dom.GetObject(cuxd+".CMD_QUERY_RET").State(1); ! Query ausführen
  string tibber_prices = dom.GetObject(""+cuxd+".CMD_RETS").State(); ! Rückgabe in Variable speichern
}
! Falls keine Strompreise verfügbar sind
if (tibber_prices=="error"){
  WriteLine("FEHLER: API nicht erreichbar! Probiere es in einer Stunde wieder...");
  quit;
}
elseif (tibber_prices.Length()<1500 || (!tibber_prices.Contains(system.Date("%F"))) ){
  WriteLine("FEHLER: Daten aus API fehlerhaft! Probiere es in einer Stunde wieder...")
  quit;
}

dom.GetObject(sysvar).State(tibber_prices); ! Preise in Systemvariable schreiben
dom.GetObject(errorvar).State(0); ! Fehler-Variable auf false setzen
WriteLine("Preise erfolgreich empfangen!");
  
! ===============
! Datenauswertung
string stdout; string stderr; integer i = 0; integer exp_hrs = 0; string inh_hrs; string inh_prices;
object arr=""; ! Variable für das Sortierskript
integer maxinhibit = dom.GetObject(inhibitmax).Value(); ! Maximale Anzahl der Sperrstunden auslesen
 
while (i<24) { ! Jede Stunde des Tages auswerten
  system.Exec( "node -e 'console.log( " # tibber_prices # ".data.viewer.homes[0].currentSubscription.priceInfo."+period+"["+i.ToString()+"].level );'",&stdout,&stderr); if (stderr) { Write(stderr); quit; } ! Preisniveau auslesen
  ! WriteLine(i.ToString()+" Uhr: "+stdout);
  if (stdout.Contains(inhibitstring1) || stdout.Contains(inhibitstring2)){ ! Teure und ggf. normale Stromstunden zählen
      exp_hrs=exp_hrs+1;
      system.Exec( "node -e 'console.log( " # tibber_prices # ".data.viewer.homes[0].currentSubscription.priceInfo."+period+"["+i.ToString()+"].total );'",&stdout,&stderr); if (stderr) { Write(stderr); quit;} ! Preis auslesen
      inh_prices=inh_prices+stdout+";"; ! Kosten der Sperrstunde eintragen
      arr=arr + stdout + "/"; ! Kosten der Sperrstunde eintragen
      system.Exec( "node -e 'console.log( " # tibber_prices # ".data.viewer.homes[0].currentSubscription.priceInfo."+period+"["+i.ToString()+"].startsAt );'",&stdout,&stderr); if (stderr) { Write(stderr); quit; } ! Zeitpunkte auslesen
      inh_hrs=inh_hrs+stdout.Substr(11,2)+";"; ! Sperrzeiten eintragen
      arr=arr + stdout.Substr(11,2) + ";"; ! Sperrzeiten eintragen
      };
  i=i+1;
}
inh_hrs=inh_hrs.Substr(0,inh_hrs.Length()-1); ! Letztes ; entfernen
inh_prices=inh_prices.Substr(0,inh_prices.Length()-1); ! Letztes ; entfernen
inh_prices=inh_prices.Replace("\n",""); ! Umbrüche entfernen
arr=arr.Replace("\n",""); ! Umbrüche entfernen
 
! Sortierskript von Tyfys zum Begrenzen der maximalen Sperrzeit
! ---------------------------------------------------------------------------  
if (exp_hrs > maxinhibit) { ! Sperrstunden begrenzen falls nötig
    WriteLine("Heizung würde heute für "+exp_hrs.ToString()+" Stunden gesperrt. Es wird auf die "+maxinhibit.ToString(0)+" teuersten Stunden begrenzt:");
    object arrtyp  ="n;n"; ! Element Art  n=numerisch / a=alphanumerisch

    var sep1=";"; ! Trennzeichen für Stunden
    var sep2="/"; ! Trennzeichen für Preis und Stunde

    ! Tauschstrings von > nach
    string av;
    string an;
    integer len = web.webGetValueListCount(arr).ToInteger() - 1;
    boolean swapped = true;
    var elemart = "a";
    string index;
    integer von = 0;
    integer bis = 1;

    foreach(index, system.GenerateEnum(von, bis)) {
      integer x = (von + bis) - index.ToInteger();
      elemart = arrtyp.StrValueByIndex(sep1, x);
      swapped = true;
      while (swapped) {
        i = 1;
        swapped = false;
          while (i <= len) {
            if (((elemart <> "n") && ((arr.StrValueByIndex(sep1, i).StrValueByIndex(sep2, x).ToUpper()) < (arr.StrValueByIndex(sep1, i - 1).StrValueByIndex(sep2, x).ToUpper())))
                 || ((elemart == "n") && ((arr.StrValueByIndex(sep1, i).StrValueByIndex(sep2, x).ToFloat()) < (arr.StrValueByIndex(sep1, i - 1).StrValueByIndex(sep2, x).ToFloat())))) {
                av = arr.StrValueByIndex(sep1, i - 1) # sep1 # arr.StrValueByIndex(sep1, i);
                an = arr.StrValueByIndex(sep1, i) # sep1 # arr.StrValueByIndex(sep1, i - 1);
                arr = arr.Replace(av, an);
                swapped = true;
            }
            i = i + 1;
          }
      }
    }
    string ix;
    object arr2 = "";
    string elem;
    foreach(elem, arr.Split(";")) {
      arr2 = elem # sep1 # arr2;
    }
    arr = arr2;
    inh_hrs="";
    inh_prices="";
    foreach(ix, system.GenerateEnum(0, maxinhibit-1)) {
      WriteLine((ix.ToInteger() + 1) # ".  " # (arr.StrValueByIndex(sep1, ix).StrValueByIndex(sep2, 0)) # " EUR ab " # (arr.StrValueByIndex(sep1, ix).StrValueByIndex(sep2, 1)) # " Uhr" );
      inh_hrs = inh_hrs + arr.StrValueByIndex(sep1, ix).StrValueByIndex(sep2, 1) + ";"; ! Sortierte Sperrzeiten schreiben
      inh_prices = inh_prices + arr.StrValueByIndex(sep1, ix).StrValueByIndex(sep2, 0) + ";"; ! Sortierte Sperrpreise schreiben
    }
  exp_hrs=maxinhibit;
  inh_hrs=inh_hrs.Substr(0,inh_hrs.Length()-1); ! Letztes ; entfernen
  inh_prices=inh_prices.Substr(0,inh_prices.Length()-1); ! Letztes ; entfernen
};
! ---------------------------------------------------------------------------
WriteLine("Heizung wird heute für "+exp_hrs.ToString(0)+" Stunden gesperrt.");
  
dom.GetObject(inhibitvar).State(inh_hrs); ! SV schreiben
dom.GetObject(inhibithrs).State(exp_hrs); ! SV schreiben
dom.GetObject(inhibitprices).State(inh_prices); ! SV schreiben
    
dom.GetObject(ID_PROGRAMS).Get("TIBBER-Strompreis stündlich auswerten").ProgramExecute(); ! Auswertung direkt starten
2. Strompreis stündlich auswerten (die letzte Zeile auskommentieren, wenn ihr das Display nicht verwendet)

Code: Alles auswählen

! == Tibber-Strompreise Skript (Stündliche Ausführung) ==
! v1.3 (2024-02-21) Mic4rd
! Dank an MichaelN und Tyfys
! Quelle und Hinweise: https://homematic-forum.de/forum/viewtopic.php?f=19&t=79588&start=20#p787998

! Eingabe:
string channel_inhibit = "Heizungssperre-Tibber"; ! Hier den Namen der Systemvariable oder des Kanals eintragen, der eine Sperre der Heizung bewirkt
string SV_pricing_today = "TIBBER_Strompreise"; ! Hier die Systemvariable eintragen, in welcher die Preise von heute sind
string SV_current_price = "TIBBER_Strompreis_aktuell"; ! Hier die Systemvariable eintragen, in welche der aktuelle Preis geschrieben werden soll
string SV_current_level = "TIBBER_Preisniveau_aktuell"; ! Hier die Systemvariable eintragen, in welche das aktuelle Preisniveau geschrieben werden soll
string inhibitvar = "TIBBER_Sperrzeiten"; ! Hier Namen der Systemvariablen eintragen, in den die Sperrzeiten eingetragen sind
string SV_errorvar = "TIBBER_API-Fehler"; ! Hier Namen der Systemvariablen eintragen, welchen einen API-Fehler anzeigt

! =================================
! Ausführung, ab hier nichts ändern
string period = "today"; 
string hour2check =  system.Date("%H"); ! Aktuelle Stunde auslesen
string tibber_prices = dom.GetObject(SV_pricing_today).Value(); ! Strompreise auslesen

string stdout; string stderr; ! API Auslesevariablen

! Falls keine Strompreise verfügbar sind
if (tibber_prices.Contains("error") || tibber_prices.Length()==0){
  WriteLine("FEHLER: Kein Strompreis verfügbar.");
  dom.GetObject(SV_current_price).State("error");
  dom.GetObject(SV_current_level).State("error");
  dom.GetObject(SV_errorvar).State(1); ! API-Fehler setzen
  quit;}

! Aktuelle Werte auslesen und abspeichern
system.Exec( "node -e 'console.log( " # tibber_prices # ".data.viewer.homes[0].currentSubscription.priceInfo."+period+"["+hour2check+"].total );'",&stdout,&stderr); if (stderr) { Write(stderr); quit; } ! Aktuellen Strompreis auslesen
WriteLine("Strompreis ab "+hour2check+" Uhr: "+stdout.Replace("\n","")+" EUR/kWh");
dom.GetObject(SV_current_price).State(stdout.ToFloat()); ! Aktuellen Strompreis in die Systemvariable schreiben

system.Exec( "node -e 'console.log( " # tibber_prices # ".data.viewer.homes[0].currentSubscription.priceInfo."+period+"["+hour2check+"].level );'",&stdout,&stderr); if (stderr) { Write(stderr); quit; } ! Aktuelles Preisniveau auslesen
WriteLine("Preisniveau ab "+hour2check+" Uhr: "+stdout);
dom.GetObject(SV_current_level).State(stdout); ! Aktuelles Preisniveau in die Systemvariable schreiben

WriteLine("Sperrzeiten: "+dom.GetObject(inhibitvar).Value());

if (dom.GetObject(inhibitvar).Value().Contains(hour2check)) { ! Wenn aktuelle Stunde eine Sperrzeit ist
  WriteLine("Teurer Strom erkannt, Heizung wird gesperrt!");
  dom.GetObject(channel_inhibit).State(1); ! Heizung sperren
  WriteLine("Sperrstatus: "#dom.GetObject(channel_inhibit).State());}
else { ! Aktuelle Stunde ist keine Sperrstunde
  WriteLine("Strompreis normal oder günstig, Heizung wird freigegeben!");
  dom.GetObject(channel_inhibit).State(0); ! Heizung freigeben
  WriteLine("Sperrstatus: "#dom.GetObject(channel_inhibit).State());}

dom.GetObject(ID_PROGRAMS).Get("Display updaten").ProgramExecute(); ! Display-Update direkt starten
3. Strompreis des Folgetags mittags holen

Code: Alles auswählen

! == Tibber-Strompreise Skript Nächster Tag (Tägliche Ausführung um 13:17 Uhr) ==
! v1.2 (2024-06-04) Mic4rd
! Quelle und Hinweise: https://homematic-forum.de/forum/viewtopic.php?f=19&t=79588&start=20#p787998

! Eingabe:
string apikey = "xxx"; ! Hier deinen persönlichen Tibber-API-Key eintragen
string cuxd = "CUxD.CUX2801001:1"; ! Hier dein CUXD-Device eintragen
string sysvar = "TIBBER_Strompreise_morgen"; ! Hier Namen der Systemvariablen (String) eintragen, in welche die Preise geschrieben werden sollen
string errorvar = "TIBBER_API-Fehler"; ! Hier Namen der Systemvariablen (Bool) eintragen, welchen einen API-Fehler anzeigt
string pricesmissingvar = "TIBBER_API-Morgen-fehlt"; ! Hier Namen der Systemvariablen (Bool) eintragen, welcher anzeigt, dass Preise noch nicht verfügbar sind

! =================================
! Ausführung, ab hier nichts ändern
string period = "tomorrow";
dom.GetObject(sysvar).State("error"); ! Wert auf error setzen, falls mit dem Abrufen etwas schiefgehen sollte
dom.GetObject(errorvar).State(1); ! Fehlervariable auf true setzen, falls mit dem Abrufen etwas schiefgehen sollte
var tibberpriceurl="curl -H \"Authorization: Bearer "+apikey+"\" -H \"Content-Type: application/json\" -X POST -d  '{ \"query\": \"{viewer {homes {currentSubscription {priceInfo {"+period+" {startsAt total level}}}}}}\" }' https://api.tibber.com/v1-beta/gql"; ! Tibber API URL
dom.GetObject(cuxd+".CMD_SETS").State(tibberpriceurl); ! Query-Ziel setzen
dom.GetObject(cuxd+".CMD_QUERY_RET").State(1); ! Query ausführen
string tibber_prices = dom.GetObject(""+cuxd+".CMD_RETS").State(); ! Rückgabe in Variable speichern
WriteLine("API-Antwort: "+tibber_prices);

! Falls keine Strompreise verfügbar sind
WriteLine(system.Date("%d").ToInteger()+1);
if (system.Date("%d").ToInteger()+1 < 10){
  string dateTMR = system.Date("%Y-%m-%d").Replace(system.Date("%d"),"0"+system.Date("%d").ToInteger()+1);
}
else {
  string dateTMR = system.Date("%Y-%m-%d").Replace(system.Date("%d"),system.Date("%d").ToInteger()+1);
}
WriteLine("Datum morgen: "+dateTMR+", Länge der API-Antwort: "+tibber_prices.Length());
if (tibber_prices=="error"){
  WriteLine("FEHLER: Keine Antwort von der API erhalten!");
}
elseif (tibber_prices.Contains("tomorrow") && (!tibber_prices.Contains(dateTMR) || tibber_prices.Length()<1500) ){
  WriteLine("FEHLER: Ungültige Daten empfangen!");
}
elseif (tibber_prices.Contains("tomorrow") && (tibber_prices.Length()<1500)){
  dom.GetObject(sysvar).State(tibber_prices); ! Preise in Systemvariable schreiben
  dom.GetObject(errorvar).State(0); ! Fehler-Variable auf false setzen
  dom.GetObject(pricesmissingvar).State(1); ! Preis-Fehlt-Variable auf true setzen
  WriteLine("WARNUNG: API Kommunikation OK, Strompreise von morgen sind jedoch noch nicht verfügbar!");
}
else {
  dom.GetObject(sysvar).State(tibber_prices); ! Preise in Systemvariable schreiben
  dom.GetObject(errorvar).State(0); ! Fehler-Variable auf false setzen
  dom.GetObject(pricesmissingvar).State(0); ! Preis-Fehlt-Variable auf false setzen
  WriteLine("Preise erfolgreich empfangen!");
  }
4. (Optional) Strompreis und Tendenz auf HmIP-WRCD anzeigen

Code: Alles auswählen

! == Tibber-Strompreise Skript Preise auf WRCD-Display anzeigen ==
! v1.2 (2024-02-21) Mic4rd
! Quelle und Hinweise: https://homematic-forum.de/forum/viewtopic.php?f=19&t=79588&start=20#p787998

! Eingabe:
string SV_pricing_today = "TIBBER_Strompreise"; ! Hier die Systemvariable eintragen, in welcher die Preise von heute sind
string SV_pricing_tomorrow = "TIBBER_Strompreise_morgen"; ! Hier die Systemvariable eintragen, in welcher die Preise von morgen sind
string SV_current_price = "TIBBER_Strompreis_aktuell"; ! Hier die Systemvariable eintragen, in welche der aktuelle Preis geschrieben werden soll
string SV_current_level = "TIBBER_Preisniveau_aktuell"; ! Hier die Systemvariable eintragen, in welche das aktuelle Preisniveau geschrieben werden soll
string inhibitvar = "TIBBER_Sperrzeiten"; ! Hier Namen der Systemvariablen eintragen, in den die Sperrzeiten eingetragen sind
string SV_DisplayUpdates = "DisplayUpdates"; ! Hier Namen der Systemvariablen der Display Updates eintragen
string SV_presence = "Anwesenheit"; ! Hier Namen der Systemvariablen der Anwesenheit eintragen

! =================================
! Ausführung, ab hier nichts ändern

if (!dom.GetObject(SV_presence).Value()){
  WriteLine("Niemand zuhause, tue nichts.")
  quit; ! Display nicht updaten, wenn niemand da ist
}

real Preis = dom.GetObject(SV_current_price).Value()*100; ! Aktuellen Preis auslesen und in Cent konvertieren
string Niveau = dom.GetObject(SV_current_level).Value().Replace("\n",""); ! Aktuelles Preisniveau auslesen
integer hour2check = system.Date("%H").ToInteger(); ! Aktuelle Stunde auslesen
string Niveau_ger ="";
integer DisplayUpdates = dom.GetObject(SV_DisplayUpdates).Value(); ! Zählervariable
string tibber_prices = dom.GetObject(SV_pricing_today).Value(); ! Strompreise auslesen

! Preisniveau auf deutsch bestimmen. "Mittelteuer", wenn aktuelle Stunde eine Sperrzeit ist und Preis nicht EXPENSIVE oder VERY_EXPENSIVE
if (dom.GetObject(inhibitvar).Value().Contains(system.Date("%H")) && (Niveau.Find("EXPENSIVE")=="-1")) {Niveau_ger = "Mittelteuer";} 
elseif (Niveau == "VERY_CHEAP") {Niveau_ger = "Sehr billig";}
elseif (Niveau == "CHEAP") {Niveau_ger = "Billig";}
elseif (Niveau == "NORMAL") {Niveau_ger = "Mittel";}
elseif (Niveau == "EXPENSIVE") {Niveau_ger = "Teuer";}
elseif (Niveau == "VERY_EXPENSIVE") {Niveau_ger = "Sehr teuer";}

! Preise der folgenden Stunden ermitteln
string period = "today";
string stdout; string stderr; ! API Auslesevariablen

integer hour2check1 = hour2check+1; ! Nächste Stunde
if (hour2check1 > 23) {hour2check1=hour2check1-24; period="tomorrow"; tibber_prices = dom.GetObject(SV_pricing_tomorrow).Value();} ! Ab 0 Uhr zum nächsten Tag springen
system.Exec( "node -e 'console.log( " # tibber_prices # ".data.viewer.homes[0].currentSubscription.priceInfo."+period+"["+hour2check1.ToString(0)+"].total );'",&stdout,&stderr); if (stderr) { Write(stderr); quit; } ! Strompreis der nächsten Stunde auslesen (in EUR)
string hourplus1 = stdout.Replace("\n","").ToFloat()*100; ! Speichern als Cent-Betrag
  
integer hour2check2 = hour2check+2; ! Übernächste Stunde
if (hour2check2 > 23) {hour2check2=hour2check2-24; period="tomorrow"; tibber_prices = dom.GetObject(SV_pricing_tomorrow).Value();} ! Ab 0 Uhr zum nächsten Tag springen
system.Exec( "node -e 'console.log( " # tibber_prices # ".data.viewer.homes[0].currentSubscription.priceInfo."+period+"["+hour2check2.ToString(0)+"].total );'",&stdout,&stderr); if (stderr) { Write(stderr); quit; } ! Strompreis der übernächsten Stunde auslesen (in EUR)
string hourplus2 = stdout.Replace("\n","").ToFloat()*100; ! Speichern als Cent-Betrag

WriteLine("Aktuell: "+Preis.ToString(1)+" Ct, ab "+(hour2check1).ToString(0)+"h: "+hourplus1.ToString(1)+" Ct und ab "+hour2check2.ToString(0)+"h : "+hourplus2.ToString(1)+" Ct.");

! Trendsymbole bestimmen
integer lowstep=1; ! Nötige Preisabweichung in ct/kWh (min: 1) für Symbol %u2197 oder %u2198
integer highstep=3; ! Nötige Preisabweichung in ct/kWh (min: 2) für Symbol %u2191 oder %u2193
! Symbol für nächste Stunde
if (hourplus1.Round(0).ToInteger() > (Preis+highstep-1).Round(0).ToInteger()) {string symbolplus1="=";}
elseif (hourplus1.Round(0).ToInteger() > (Preis+lowstep-1).Round(0).ToInteger()) {string symbolplus1=">";}
elseif ((hourplus1+lowstep-1).Round(0).ToInteger() < Preis.Round(0).ToInteger()) {string symbolplus1="@";}
elseif ((hourplus1+highstep-1).Round(0).ToInteger() < Preis.Round(0).ToInteger()) {string symbolplus1="<";}
else {string symbolplus1="'";}
! Symbol für übernächste Stunde
if (hourplus2.Round(0).ToInteger() > (hourplus1+highstep-1).Round(0).ToInteger()) {string symbolplus2="=";}
elseif (hourplus2.Round(0).ToInteger() > (hourplus1+lowstep-1).Round(0).ToInteger()) {string symbolplus2=">";}
elseif ((hourplus2+lowstep-1).Round(0).ToInteger() < hourplus1.Round(0).ToInteger()) {string symbolplus2="@";}
elseif ((hourplus2+highstep-1).Round(0).ToInteger() < hourplus1.Round(0).ToInteger()) {string symbolplus2="<";}
else {string symbolplus2="'";}

! Display Zeilen definieren
string line2 = Preis.ToString(1)+" ct/kWh";
string line3 = Niveau_ger;
string line4 = "Tendenz "+symbolplus1+" "+symbolplus2;

string update_string = "{DDBC=WHITE,DDTC=BLACK,DDI=0,DDA=CENTER,DDS="+line2+",DDID=2},"+
                       "{DDBC=WHITE,DDTC=BLACK,DDI=0,DDA=CENTER,DDS="+line3+",DDID=3},"+
                       "{DDBC=WHITE,DDTC=BLACK,DDI=0,DDA=CENTER,DDS="+line4+",DDID=4,DDC=true}";
dom.GetObject("HmIP-RF.002A60C9950C5B:3.COMBINED_PARAMETER").State(update_string);
DisplayUpdates=DisplayUpdates+1; ! Display Zähler erhöhen
dom.GetObject(SV_DisplayUpdates).State(DisplayUpdates); ! Display Zähler schreiben

WriteLine("Display wird aktualisiert (Zähler: "+DisplayUpdates.ToString(0)+"). Ausgabe:\n=============\n"+line2+"\n"+line3+"\n"+line4+"\n=============");
Bild
(Anmerkung: Die "Display Updates" sind einfach ein Zähler, der die Display Updates zählt. Das war anfangs wichtig, da das WRCD bei zu häufigem Ansprechen in einen "Burst-Limit" Modus geht um Batterie zu sparen. Die Zeilen 1 und 5 verwende ich als zustandsabhängige Buttons zur Tesla-Steuerung, daher war der Zähler wichtig. Für die hier vorliegenden Skripte habt ihr nur ein Update pro Stunde, was kein Problem darstellt. Zu Debug-Zwecken habe ich das Update-Logging aber nicht rausgenommen.)

Es sind ein paar mehr Systemvariablen notwendig, dies geht aus dem Eingabebereich der Skripte direkt hervor. Habe alle 4 Skripte seit mind. 2 Monaten problemlos laufen, vielleicht nützen sie ja noch jemandem ;-) Keine Probleme mit CPU/RAM-Auslastung mit Raspberrymatic auf einem RasPi 4.

Antworten

Zurück zu „HomeMatic allgemein“