TCL(?)-Script erstellung, Heizungsdaten auslesen

Homematic-, TCL- und Shell-Script, Toolchain, C, etc.

Moderator: Co-Administratoren

Tyfys
Beiträge: 551
Registriert: 17.04.2021, 17:12
System: CCU
Hat sich bedankt: 27 Mal
Danksagung erhalten: 125 Mal

Re: TCL(?)-Script erstellung, Heizungsdaten auslesen

Beitrag von Tyfys » 25.11.2023, 16:36

Hallo Chris

Wieso die Daten für den Abruf für 1.cgi und 2.cgi nun einen anderen Aufbau haben ist für mich nicht nachvollziehbar.

Jedenfalls war es bei den Daten von massel so, dass die pos-Elemente mit den graden Zahlen ( 0,2,4,6 etc )
die Namen und die pos-Elemente mit den ungraden Zahlen ( 1,3,5,7 etc ) dann den Wert enthalten.
Zumindest für die Pos 1-29. Ab 34 dann ein anderes Schema.

Bei dir enthält nun jedes pos-Element den Wert.
Für was der denn steht muss also wo anders definiert werden.

Das habe ich in der Skriptvariablen arr gemacht. ( von mir nur mit Beispieldaten gefüllt)
und zwar immer paarweise das pos-Element und Systemvariablenname durch Schrägstrich ("/") getrennt.
Das nächste Paar wird dann mit Semikolon getrennt angehängt. Usw,.

Es müssen nur die Paare eingetragen werden, die du haben willst.

Hier nun das erste Skript für Aufruf im Fenster Skript testen: ( Du musst natürlich natürlich IP-Adresse und Anmeldedaten entsprechen ändern)

Code: Alles auswählen

! CMI-Heizungsdaten  Systemvariablennamen anlisten
!**************************************************************
! Variablen und Werte für die ersten 30 ids
! Variablen mit Temperaturangaben anlegen als Variablentyp Zahl °C als Masseinheit angeben
! Variablen nicht mit Temperaturangaben anlegen als Variablentyp Logikwert  ( wahr = an  / falsch = aus
!**************************************************************

string  url = "http://admin:admin@192.168.178.95/schematic_files/1.cgi";
integer von = 0;  !erste div id pos nr
integer bis = 30; !letzte div id pos nr
string  arr= "pos0/Temperatur1;pos1/Temperatur2;pos3/Zuluftklappe;pos10/Temperaturvorne";
string  stdout;
string  stderr;
string  suche = '<div id="pos';
string  such2 = '</div>';
string  index;
string  wert;
string  sysvar;
real    sv_value;

system.Exec("wget --no-check-certificate -q -O - '" # url # "'", &stdout, &stderr);
if (stdout.Length() == 0)
{
    WriteLine("keine Daten empfangen");
    if (stderr.Length() > 0)
    {
        WriteLine("Fehlermeldung vom Server: " # stderr);
    }
    quit;
}
else
{
    !WriteLine(stdout);
}

stdout = stdout.ToLatin();
stdout = stdout.Replace("\n", "");  ! Zeilenumbrüche entfernen
stdout = stdout.Replace("\r", "");  ! da sonst auch im VariablenName bzw VariablenWert 
stdout = stdout.Replace(" °C", ""); ! Masseinheit entfernen
stdout = stdout.Replace("Auto/AUS" , "0");
stdout = stdout.Replace("Auto/EIN", "1");
stdout = stdout.Replace("Auto", "0");
stdout = stdout.Replace("OFF", "0");
stdout = stdout.Replace("ON", "1");
stdout = stdout.Replace("AUS", "0");
stdout = stdout.Replace("EIN", "1");

foreach(index, system.GenerateEnum(von, bis)) {
    var such1 = suche # index;
    if (stdout.Contains(such1)) {
        string such = such1.Replace('<div id="', "") # "/";
        if (arr.Contains(such)) {
            integer pos = web.webGetValueListCount(arr.Substr(0, arr.Find(such) + such.Length())).ToInteger() - 1;
            sysvar = (arr.StrValueByIndex(";", pos)).StrValueByIndex("/", 1);
            wert = stdout.Substr(stdout.Find(such1) + such1.Length()).Substr(0, (stdout.Substr(stdout.Find(such1) + such1.Length()).Find(such2)));
            wert = wert.Substr(wert.Find(">") + 1);
            Write("Für " # such1.LTrim("<"));
            sv_value = wert.ToFloat();
            Write("    mit   Wert: " # sv_value);
            WriteLine(" eine Systemvariable mit Namen " # sysvar # " anlegen");
        }
    } else {
        WriteLine("Element " # such1 # " ist im Datensatz nicht enthalten");
    }
}
wenn alles soweit passt und die Variablen angelegt sind , kannst du dieses Skript auch noch einmal im Test-Fenster aufrufen:

Code: Alles auswählen

! CMI-Heizungsdaten  anlisten /ausgeben in Systemvariablen
!**************************************************************
! Variablen mit Temperaturangaben anlegen als Variablentyp Zahl °C als Masseinheit angeben
! Variablen nicht mit Temperaturangaben anlegen als Variablentyp Logikwert  ( wahr = an  / falsch = aus
!**************************************************************

string  url = "http://admin:admin@192.168.178.95/schematic_files/1.cgi";
integer von = 0;  !erste div id pos nr
integer bis = 30; !letzte div id pos nr
!Zuordnung der gewünschten Systemvariablen zu posx
string  arr = "pos0/Temperatur1;pos1/Temperatur2;pos3/Zuluftklappe;pos10/Temperaturvorne";

string  stdout;
string  stderr;
string  suche = '<div id="pos';
string  such2 = '</div>';
string  index;
string  wert;
string  sysvar;
real    sv_value;

system.Exec("wget --no-check-certificate -q -O - '" # url # "'", &stdout, &stderr);
if (stdout.Length() == 0)
{
    WriteLine("keine Daten empfangen");
    if (stderr.Length() > 0)
    {
        WriteLine("Fehlermeldung vom Server: " # stderr);
    }
    quit;
}
else
{
    WriteLine(stdout);
}

stdout = stdout.ToLatin();
stdout = stdout.Replace("\n", "");  ! Zeilenumbrüche entfernen
stdout = stdout.Replace("\r", "");  ! da sonst auch im VariablenName bzw VariablenWert 
stdout = stdout.Replace(" °C", ""); ! Masseinheit entfernen
stdout = stdout.Replace("Auto/AUS" , "0");
stdout = stdout.Replace("Auto/EIN" , "1");
stdout = stdout.Replace("Auto" , "0");
stdout = stdout.Replace("OFF", "0");
stdout = stdout.Replace("ON", "1");
stdout = stdout.Replace("AUS", "0");
stdout = stdout.Replace("EIN", "1");

foreach(index, system.GenerateEnum(von, bis)) {
    var such1 = suche # index;
    if (stdout.Contains(such1)) {
        string such = such1.Replace('<div id="', "") # "/";
        if (arr.Contains(such)) {
            integer pos = web.webGetValueListCount(arr.Substr(0, arr.Find(such) + such.Length())).ToInteger() - 1;
            sysvar = (arr.StrValueByIndex(";", pos)).StrValueByIndex("/", 1);
            wert = stdout.Substr(stdout.Find(such1) + such1.Length()).Substr(0, (stdout.Substr(stdout.Find(such1) + such1.Length()).Find(such2)));
            wert = wert.Substr(wert.Find(">") + 1);
            Write("Für " # such1.LTrim("<"));
            sv_value = wert.ToFloat();
            object svdp = dom.GetObject(ID_SYSTEM_VARIABLES).Get(sysvar);
            if (svdp) {
                svdp.State(sv_value);
                WriteLine(" Variable: " # sysvar # " gespeichert mit Wert " # sv_value);
            } else {
                WriteLine(" Variable: " # sysvar # " nicht angelegt für Wert " # sv_value);
            }
        }
    } else {
        WriteLine("Element " # such1 # " ist im Datensatz nicht enthalten");
    }
}


Wenn denn alles richtig ist, dieses Skript dann in das periodische Programm einfügen.
Die WriteLine() kannst dann entfernen oder auskommentieren.
Gruß
Harry

ChrisL
Beiträge: 344
Registriert: 25.05.2011, 08:31

Re: TCL(?)-Script erstellung, Heizungsdaten auslesen

Beitrag von ChrisL » 25.11.2023, 19:17

Hallo Harry,

die Steuerung ist ja frei programmierbar und ich denke, da macht jeder seine eigene Suppe.
Hier mal der Output des ersten Scripts:

Code: Alles auswählen

Für div id="pos0    mit   Wert: 3.000000 eine Systemvariable mit Namen Temperatur1 anlegen
Für div id="pos1    mit   Wert: 31.200000 eine Systemvariable mit Namen Temperatur2 anlegen
Für div id="pos3    mit   Wert: 0.000000 eine Systemvariable mit Namen Zuluftklappe anlegen
Für div id="pos10    mit   Wert: 69.400000 eine Systemvariable mit Namen Temperaturvorne anlegen
Da fehlen aber einige Werte. Ist wohl etwas durcheinander bei meiner Steuerung.

Viele Grüße
Chris

Benutzeravatar
Baxxy
Beiträge: 10847
Registriert: 18.12.2018, 15:45
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 610 Mal
Danksagung erhalten: 2229 Mal

Re: TCL(?)-Script erstellung, Heizungsdaten auslesen

Beitrag von Baxxy » 25.11.2023, 19:20

ChrisL hat geschrieben:
25.11.2023, 19:17
Da fehlen aber einige Werte.
Klar, du musst selbst die Liste erweitern:

Code: Alles auswählen

string  arr= "pos0/Temperatur1;pos1/Temperatur2;pos3/Zuluftklappe;pos10/Temperaturvorne";

Tyfys
Beiträge: 551
Registriert: 17.04.2021, 17:12
System: CCU
Hat sich bedankt: 27 Mal
Danksagung erhalten: 125 Mal

Re: TCL(?)-Script erstellung, Heizungsdaten auslesen

Beitrag von Tyfys » 25.11.2023, 20:06

Hallo Chris.

Ich weiss ja nicht , welche Werte du da haben willst und was was ist. -Wie gesagt ich habe diese Heizung nicht

Daher muss du , wie Baxxy auch schon schrieb ,
in die Skriptvariable arr die gewünschten Zuordnungen schreiben.

Also quasi Element pos0 will ich in die Systemvariable abc haben.
Element pos1 will ich in die Systemvariable def haben.
Element pos2 will ich in die Systemvariable ghi haben.
usw.
Wenn du z.B. Element pos11 nicht(mehr) haben willst einfach diese Zuordnung weglassen.
Kann aber jederzeit auch nachträglich eingetragen werden.

Mein Füllen der Variable arr war ja nur zur Demonstration des Prinzips.

Wenn du alle gewünschten Zuordnungen gemacht hast, brauchst du nachher nur die Variable arr in das andere Skript zu übernehmen,
Gruß
Harry

ChrisL
Beiträge: 344
Registriert: 25.05.2011, 08:31

Re: TCL(?)-Script erstellung, Heizungsdaten auslesen

Beitrag von ChrisL » 25.11.2023, 20:30

Hallo Harry,

du bist der BESTE! Vielen Dank!!!

Es funktioniert und nun werden alle 5 Minuten die Variablen befüllt.

Viele Grüße
Chris
Bildschirmfoto 2023-11-25 um 20.30.01.png

Tyfys
Beiträge: 551
Registriert: 17.04.2021, 17:12
System: CCU
Hat sich bedankt: 27 Mal
Danksagung erhalten: 125 Mal

Re: TCL(?)-Script erstellung, Heizungsdaten auslesen

Beitrag von Tyfys » 25.11.2023, 20:44

Na prima.
Dann konnte ich mich ja doch noch verständlich ausdrücken. :mrgreen:
Gruß
Harry

Antworten

Zurück zu „Softwareentwicklung für die HomeMatic CCU“