Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

HMIP lokale Installation

Moderator: Co-Administratoren

Henke
Beiträge: 144
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 39 Mal
Danksagung erhalten: 38 Mal

Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

Beitrag von Henke » 06.09.2022, 18:03

Um zusätzlich zum Carrier Sense und Duty Cycle mir die CCU-Auslastung, Temperatur und die Loads anzeigen zu lassen bzw. im Historian auszuwerten, habe ich ein Script gebastelt, das alle 1 Minuten aufgerufen wird.

Vielleicht kann das von euch auch jemand gebrauchen.

Ziel:
Screenshot 2022-09-08 161120.jpg
Anzeige RasberryMatic
Screenshot 2022-09-24 200209.jpg
Info Feld mit Warnungen
Screenshot 2022-09-24 200209.jpg (18.47 KiB) 177 mal betrachtet
Screenshot 2022-09-08 160513.jpg
Auswertung CCU-Historian
Implementierung:
Script:

Code: Alles auswählen

!CCU - Auslastung / Temperatur
!V 1.5 Copyleft M.Henke
!https://homematic-forum.de/forum/viewtopic.php?f=60&t=75415
!-----------------
!Installation CCU3 Gerät mit Duty Cycle und Carrier Sense mit originaler Firmware siehe:
!https://homematic-forum.de/forum/viewtopic.php?f=31&p=636443#p636443
!-----------------
!-V 1.?
!CCU - Auslastung hinzugefügt
!Fehlerkorrektur Interne Variable
!Uptime CCU hinzugefügt
!Info Feld hinzugefügt mit Anzeige des ausgewerteten Intervalls und der Laufzeit der CCU
!Variable entfernt, Datenspeicherung über MetaTags
!Optimierung Code
!Anfragen unter 10 sec werden ignoriert
!-V 1.4
!CCU Last auf 60 sec normiert -> raus, Blödsinn
!Duty Cycle und Carrier Sense hinzugefügt
!-V 1.5
!Aufteilung Zeilenweise, html Ausgabe genutzt
!Anzeige Warnungen
!Fehler: Läuft nicht bei Neuinstallation behoben  

!Hier anpassen
real temperatur_hoch = 58.0;
real temperatur_kritisch = 60.0;

real Usage_hoch = 20.0;
real Usage_kritisch = 60.0;

real duty_cycle_hoch = 20.0;
real duty_cycle_kritisch = 50.0;

real Carrier_Sense_hoch = 10.0;
real Carrier_Sense_kritisch = 20.0;

!Ab hier Änderung eigentlich nicht nötig

string sv_Gruppe = "CCU3"; !Gruppenname der Systemvariablen
string sv_CPU_Info = "Info"; !CCU - Info Feld
string sv_CPU_Temp = "Temp"; !CCU - Temperatur
string sv_Load_1 = "Load.01"; !CCU - Load Schnitt 1 Minute
string sv_Load_5 = "Load.05"; !CCU - Load Schnitt 5 Minuten
string sv_Load_15 = "Load.15"; !CCU - Load Schnitt 15 Minuten
string sv_CPU_usage = "CPU_Usage"; !CPU Auslastung zwischen den Aufrufen des Scripts

!Ab hier definitiv keine Änderung nötig
boolean debug = false;
boolean CsDcOk = false;
integer srcId = ("$src$").ToInteger();
if (srcId > 0) {
    object oSrc = dom.GetObject(srcId);
    if (!oSrc) { quit; };
}
else { quit; }

object oPrg = dom.GetObject("$this$");
if (!oPrg) { quit; };

if (oSrc.Type() == OT_CALENDARDP) {
    string s;
    integer run = 0;
    !WriteLine(oSrc.TypeName());
    foreach(s, oPrg.Rule().RuleConditions().EnumIDs()) {
        object o = dom.GetObject(s);
        !WriteLine(run);

        !erster Aussenbereich
        if (!run) {
            if (o.CndSingleCount() >= 2) {
                idarray                    iaGruppeInnen = o.CndSingleConditions();
                integer dp1 = iaGruppeInnen.GetAt(1).LeftVal();
                object oTi = dom.GetObject(dp1);
                object oTHi = channels.Get(oTi.Channel());
                if (oTHi) {
                    real csl = channels.Get(oTHi).DPByHssDP("CARRIER_SENSE_LEVEL").Value();
                    real dcl = channels.Get(oTHi).DPByHssDP("DUTY_CYCLE_LEVEL").Value();
                    CsDcOk = true;
                    !WriteLine(oTHi.Name() # " " # csl.ToString(0) # " " # dcl.ToString(0));
                }
            }
            break;
        }
        run = run + 1;
    }
}

object svOj_list = dom.GetObject(ID_SYSTEM_VARIABLES);

string sv_ref_CPU_Temp = sv_Gruppe # "." # sv_CPU_Temp;
object svOj_CPU_Temp = svOj_list.Get(sv_ref_CPU_Temp);
string sv_ref_Load_1 = sv_Gruppe # "." # sv_Load_1;
object svOj_Load_1 = svOj_list.Get(sv_ref_Load_1);
string sv_ref_Load_5 = sv_Gruppe # "." # sv_Load_5;
object svOj_Load_5 = svOj_list.Get(sv_ref_Load_5);
string sv_ref_Load_15 = sv_Gruppe # "." # sv_Load_15;
object svOj_Load_15 = svOj_list.Get(sv_ref_Load_15);
string sv_ref_CPU_usage = sv_Gruppe # "." # sv_CPU_usage;
object svOj_CPU_usage = svOj_list.Get(sv_ref_CPU_usage);
string sv_ref_CPU_Info = sv_Gruppe # "." # sv_CPU_Info;
object svOj_CPU_Info = svOj_list.Get(sv_ref_CPU_Info);

!Wenn noch keine Systemvariable vorhanden, diese anlegen
if (!svOj_CPU_Temp) {
    svOj_CPU_Temp = dom.CreateObject(OT_VARDP, sv_ref_CPU_Temp);
    svOj_list.Add(svOj_CPU_Temp.ID());
    svOj_CPU_Temp.ValueType(ivtFloat);
    svOj_CPU_Temp.ValueSubType(istGeneric);
    svOj_CPU_Temp.DPInfo('CCU - Temperatur');
    svOj_CPU_Temp.ValueUnit('°C');
    svOj_CPU_Temp.ValueMin("0");
    svOj_CPU_Temp.ValueMax("200");
    svOj_CPU_Temp.Internal(false);
    svOj_CPU_Temp.Visible(true);
    dom.RTUpdate(0);
}
if (!svOj_Load_1) {
    svOj_Load_1 = dom.CreateObject(OT_VARDP, sv_ref_Load_1);
    svOj_list.Add(svOj_Load_1.ID());
    svOj_Load_1.ValueType(ivtFloat);
    svOj_Load_1.ValueSubType(istGeneric);
    svOj_Load_1.DPInfo('CCU - Load Schnitt 1 Minute');
    svOj_Load_1.ValueUnit('');
    svOj_Load_1.ValueMin("0");
    svOj_Load_1.ValueMax("10");
    svOj_Load_1.Internal(false);
    svOj_Load_1.Visible(true);
    dom.RTUpdate(0);
}
if (!svOj_Load_5) {
    svOj_Load_5 = dom.CreateObject(OT_VARDP, sv_ref_Load_5);
    svOj_list.Add(svOj_Load_5.ID());
    svOj_Load_5.ValueType(ivtFloat);
    svOj_Load_5.ValueSubType(istGeneric);
    svOj_Load_5.DPInfo('CCU - Load Schnitt 5 Minuten');
    svOj_Load_5.ValueUnit('');
    svOj_Load_5.ValueMin("0");
    svOj_Load_5.ValueMax("10");
    svOj_Load_5.Internal(false);
    svOj_Load_5.Visible(true);
    dom.RTUpdate(0);
}
if (!svOj_Load_15) {
    svOj_Load_15 = dom.CreateObject(OT_VARDP, sv_ref_Load_15);
    svOj_list.Add(svOj_Load_15.ID());
    svOj_Load_15.ValueType(ivtFloat);
    svOj_Load_15.ValueSubType(istGeneric);
    svOj_Load_15.DPInfo('CCU - Load Schnitt 15 Minuten');
    svOj_Load_15.ValueUnit('');
    svOj_Load_15.ValueMin("0");
    svOj_Load_15.ValueMax("10");
    svOj_Load_15.Internal(false);
    svOj_Load_15.Visible(true);
    dom.RTUpdate(0);
}
if (!svOj_CPU_usage) {
    svOj_CPU_usage = dom.CreateObject(OT_VARDP, sv_ref_CPU_usage);
    svOj_list.Add(svOj_CPU_usage.ID());
    svOj_CPU_usage.ValueType(ivtFloat);
    svOj_CPU_usage.ValueSubType(istGeneric);
    svOj_CPU_usage.DPInfo('CCU Usage - Durchschnitt');
    svOj_CPU_usage.ValueUnit('%');
    svOj_CPU_usage.ValueMin("0");
    svOj_CPU_usage.ValueMax("100");
    svOj_CPU_usage.Internal(false);
    svOj_CPU_usage.Visible(true);
    dom.RTUpdate(0);
}

if (!svOj_CPU_Info) {
    svOj_CPU_Info = dom.CreateObject(OT_VARDP);
    svOj_list.Add(svOj_CPU_Info);
    svOj_CPU_Info.Name(sv_ref_CPU_Info);
    svOj_CPU_Info.ValueType(ivtString);
    svOj_CPU_Info.ValueSubType(istChar8859);
    svOj_CPU_Info.DPInfo('CCU Info');
    svOj_CPU_Info.ValueUnit('');
    svOj_CPU_Info.Internal(false);
    svOj_CPU_Info.Visible(true);
    dom.RTUpdate(0);
}

string stdout; string stderr;
system.Exec("cat /sys/class/thermal/thermal_zone0/temp",& stdout, & stderr);
if (stderr) { Write(stderr); quit; }
if (debug) { WriteLine(stdout); }

real temp = stdout.ToFloat() / 1000;
if (debug) { WriteLine(temp); }
svOj_CPU_Temp.State(temp);

system.Exec("cat /proc/loadavg",& stdout, & stderr);
!if (stderr) { Write(stderr); quit; }
if (debug) { WriteLine(stdout); }

string load;
integer ii;

!1=1 Minute, 2 = 5 Minuten, 3 = 15 Minuten
real Load_1 = stdout.StrValueByIndex(" ", 0);
svOj_Load_1.State(Load_1);
real Load_5 = stdout.StrValueByIndex(" ", 1);
svOj_Load_5.State(Load_5);
real Load_15 = stdout.StrValueByIndex(" ", 2);
svOj_Load_15.State(Load_15);


!system.Exec("getconf CLK_TCK",& stdout, & stderr);
!WriteLine(stdout);

system.Exec("cat /proc/stat",& stdout, & stderr);
if (stderr) { Write(stderr); quit; }
if (debug) { WriteLine(stdout); }

string cpuKenn = "cpu  ";
integer start = stdout.Find(cpuKenn);
if (start < 0) { Write("cpu?"); quit; }
integer end = stdout.Find("\n");
if (end <= 0) { Write("end?"); quit; }

string line = stdout.Substr(start + cpuKenn.Length(), end - 1);
!WriteLine(line);

integer all = 0;
string wert;

foreach(wert, line.Split(" "))
{
    all = all + wert.ToInteger();
    !WriteLine(wert);
}
integer idle = line.StrValueByIndex(" ", 3).ToInteger();

string meta_praefix = "MH-";
string meta_key = meta_praefix # "LOG";
string sysVar_last = svOj_CPU_Info.MetaData(meta_key);
if (!sysVar_last) {
    svOj_CPU_Info.AddMetaData(meta_key);

    !Aufräumen...
    object _tickLastDel = svOj_list.Get(sv_Gruppe # "." # sv_CPU_usage # ".tickLast");
    if (_tickLastDel) {
        WriteLine("Lösche");
        svOj_list.Remove(_tickLastDel.ID());
        dom.DeleteObject(_tickLastDel.ID());
    }


    object _tickLastDel = svOj_list.Get(sv_Gruppe # "." # sv_CPU_usage # ".tickLast2");
    if (_tickLastDel) {
        svOj_list.Remove(_tickLastDel.ID());
        dom.DeleteObject(_tickLastDel.ID());
    }
}
else {
    !WriteLine("MetaDa");
}

integer allLast = 0;
integer idleLast = 0;
integer timeLast = 0;
if (sysVar_last) {
    allLast = sysVar_last.StrValueByIndex(",", 0).ToInteger();
    idleLast = sysVar_last.StrValueByIndex(",", 1).ToInteger();
    timeLast = sysVar_last.StrValueByIndex(",", 2).ToInteger();
}

!WriteLine(allLast # " " # idleLast);
string cpuKenn = "btime ";
integer start = stdout.Find(cpuKenn);
if (start < 0) { Write("btime?"); quit; }
integer end = stdout.Find("\n");
if (end <= 0) { Write("end?"); quit; }

string line = stdout.Substr(start + cpuKenn.Length(), end - 1);
!WriteLine(line.ToInteger().ToTime().ToString('%X %d.%m.%Y'));
integer timeSys = (system.Date("%F %T")).ToTime().ToInteger();
real upTimeTage = (timeSys - line.ToInteger()).ToFloat() / (60.0 * 60.0 * 24.0);
real ticksToSec = all.ToFloat() / (timeSys - line.ToInteger()).ToFloat();
!400 ?
    !WriteLine(ticksToSec);
!WriteLine(upTimeTage.ToString(2) # " Tagen");
real diff = (all.ToFloat() - allLast.ToFloat());

!WriteLine(">> " # diff);
if (allLast && (diff > 0)) {
    real cpuLast = 100.0 - (100.0 * (idle.ToFloat() - idleLast.ToFloat()) / diff);
    if (debug) { WriteLine(100.0 - (100.0 * idle.ToFloat() / all.ToFloat())); }
    if (debug) { WriteLine(cpuLast); }

    !WriteLine((diff / ticksToSec) # " " # timeDiff # "->" #(diff / timeDiff));

    !WriteLine(timeSys - timeLast);

    svOj_CPU_usage.State(cpuLast);

    if (false) {
        !alte Version Ausgabe
        if (CsDcOk) {
            string out = ""
# "Duty Cycle " # dcl.ToString(0) # " %\nCarrier Sense " # csl.ToString(0) # " %";
        }
        out = out
# "\n<b>Usage " # cpuLast.ToString(0) # " %</b>"
# "\n<i>Temperatur " # temp.ToString(0) # " °C</i>"
# "\nLoad " # Load_1.ToString(1) # " " # Load_5.ToString(1) # " "  # Load_15.ToString(1) # " "
# "\nLäuft seit " # upTimeTage.ToString(2) # " Tagen"
# "\n Delta " #(diff / ticksToSec).ToString(2) # " " #(diff / 400).ToString(2) #" sec"
            ;
    }

    string wl_alarm = "<td>&#10071;</td>";
    string wl_hoch = "<td>&#10069;</td>";
    string wl_ok = "";

    !temp = 90;
    !dcl = 40;

    string tempWl = wl_ok;
    if (temp >= temperatur_hoch) { tempWl = wl_hoch; };
    if (temp >= temperatur_kritisch) { tempWl = wl_alarm; };

    string UsageWl = wl_ok;
    if (cpuLast >= Usage_hoch) { UsageWl = wl_hoch; };
    if (cpuLast >= Usage_kritisch) { UsageWl = wl_alarm; };

    string dcWl = wl_ok;
    if (dcl >= duty_cycle_hoch) { dcWl = wl_hoch; };
    if (dcl >= duty_cycle_kritisch) { dcWl = wl_alarm; };

    string csWl = wl_ok;
    if (csl >= Carrier_Sense_hoch) { csWl = wl_hoch; };
    if (csl >= Carrier_Sense_kritisch) { csWl = wl_alarm; };

    out = ""
# "<div>"
# "<table  style=\"text-align:right; 0px 5px 0px;border: 1px solid black;border-spacing: 0px;\">"
        ;

    if (CsDcOk) {
        out = out
# "<tr>"
# "<td>Duty Cycle</td>"
# "<td><b>" # dcl.ToString(0) # "</b>" # "</td><td>" # "%" # "</td>"
# "<td>" # dcWl # "</td>"
# "</tr>"

# "<tr>"
# "<td>Carrier Sense</td>"
# "<td><b>" # csl.ToString(0) # "</b>" # "</td><td>" # "%" # "</td>"
# "<td>" # csWl # "</td>"
# "</tr>"
            ;
    }

    out = out
# "<tr>"
# "<td>Usage</td>"
# "<td><b>" # cpuLast.ToString(0) # "</b>" # "</td><td>" # "%" # "</td>"
# "<td>" # UsageWl # "</td>"
# "</tr>"

# "<tr>"
# "<td>Temperatur</td>"
# "<td><b>" # temp.ToString(0) # "</b>" # "</td><td>" # "&#8451" # "</td>"
# "<td>" # tempWl # "</td>"
# "</tr>"

# "<tr>"
# "<td>Load Ø 1 min</td>"
# "<td><b>" # Load_1.ToString(1) # "</b>" # "</td>"
# "<td></td>"
# "</tr>"

# "<tr>"
# "<td>5 min</td>"
# "<td><b>" # Load_5.ToString(1) # "</b>" # "</td>"
# "<td></td>"
# "</tr>"

# "<tr>"
# "<td>15 min</td>"
# "<td><b>" # Load_15.ToString(1) # "</b>" # "</td>"
# "<td></td>"
# "</tr>"

# "<tr>"
# "<td>Intervall</td>"
# "<td>" #(diff / ticksToSec).ToString(1) # "" # "</td><td>" # "sec" # "</td>"
# "<td></td>"
# "<td></td>"
# "</tr>"
# "</table>"
        ;
    !# "</div>"
    !# "<div style=\"background-color:rgb(255, 0, 0);\">"
    !# "Err2"
    !# "</div>"

    !WriteLine(out);
    svOj_CPU_Info.State(out.Replace("%", "&#x25;"));
}

sysVar_last = all # "," # idle # "," # timeSys;
!WriteLine(sysVar_last);
svOj_CPU_Info.MetaData(meta_key, sysVar_last);
Screenshot 2022-09-24 204340.jpg
CCU-Programm
Alle Intervalle sind ab Version 1.1 auch möglich. 5 Minuten reichen eigentlich, damit passt die Auslastung zum "Load 5". 1 Minute ist auch möglich, dann erkennt man Spitzen besser. Ich lasse es aktuell auf 5 Minuten laufen.
Ab Version 1.5 auch bitte die CCU eintragen. Duty Cycle und Carrier Sense werden dann angezeigt.
Installation CCU3 Gerät mit Duty Cycle und Carrier Sense mit originaler Firmware siehe: : viewtopic.php?f=31&p=636443#p636443

G
Michael

Edit:
  • V 1.2
  • Info Feld hinzugefügt mit Anzeige des ausgewerteten Intervalls und der Laufzeit der CCU
  • CCU Last auf 60 sec normiert
  • V 1.3
  • Variable entfernt, Datenspeicherung über MetaTags
  • Optimierung Code
  • V 1.5
  • Duty Cycle und Carrier Sense hinzugefügt
  • Aufteilung Zeilenweise, html Ausgabe genutzt
  • Anzeige Warnungen
  • Fehler: Läuft nicht bei Neuinstallation behoben
Zuletzt geändert von Henke am 25.09.2022, 18:08, insgesamt 8-mal geändert.

woggle
Beiträge: 73
Registriert: 01.02.2015, 15:31
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 43 Mal
Danksagung erhalten: 9 Mal

Re: Script CCU-Temperatur und CCU-Load in Systemvariable schreiben

Beitrag von woggle » 07.09.2022, 13:15

Danke für die Idee und das Script. Läuft prima!

Henke
Beiträge: 144
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 39 Mal
Danksagung erhalten: 38 Mal

Re: Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

Beitrag von Henke » 08.09.2022, 16:19

woggle hat geschrieben:
07.09.2022, 13:15
Danke für die Idee und das Script. Läuft prima!
Danke dir.

Ich habe den Beitrag oben aktualisiert, da jetzt auch die CPU-Auslastung ausgewertet wird.

LG
Michael

woggle
Beiträge: 73
Registriert: 01.02.2015, 15:31
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 43 Mal
Danksagung erhalten: 9 Mal

Re: Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

Beitrag von woggle » 14.09.2022, 12:56

Super, auch das läuft seit einigen Tagen problemlos!

Stigkester
Beiträge: 9
Registriert: 02.01.2021, 21:33
System: CCU
Hat sich bedankt: 2 Mal

Re: Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

Beitrag von Stigkester » 20.09.2022, 14:24

Funktioniert super.

Kann ich denn Wert in 5 anzeigen lassen?
Quasi ist Wert *100

Henke
Beiträge: 144
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 39 Mal
Danksagung erhalten: 38 Mal

Re: Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

Beitrag von Henke » 20.09.2022, 18:10

Stigkester hat geschrieben:
20.09.2022, 14:24
Kann ich denn Wert in 5 anzeigen lassen?
Quasi ist Wert *100
Sry, ich verstehe nicht, was du meinst. Aber vielleicht löst das Update ja das Problem.

Stigkester
Beiträge: 9
Registriert: 02.01.2021, 21:33
System: CCU
Hat sich bedankt: 2 Mal

Re: Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

Beitrag von Stigkester » 21.09.2022, 00:57

Der Wert load1,5 und 15 wird schon in % angezeigt?

0.61% erscheint mir zu wenig.
Wenn 1 = 100% ist also 0.61 = 61% erscheint mir zu viel?

Henke
Beiträge: 144
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 39 Mal
Danksagung erhalten: 38 Mal

Re: Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

Beitrag von Henke » 21.09.2022, 01:58

Stigkester hat geschrieben:
21.09.2022, 00:57
Der Wert load1,5 und 15 wird schon in % angezeigt?
Ich hoffe, das ich nicht irgendwo den Load in "%" angegeben habe. Das wäre falsch. Wenn dem so ist, bitte kurze Info wo genau.

Definition von Load: https://de.wikipedia.org/wiki/Load

Meine Kurzform:
Load = 0 -> CPU tot
Load < 0.4 -> CPU Koma
Load < 0.8 -> CPU schläft
Load < 1.5 -> CPU wach
Load > 1.5 -> CPU muss arbeiten

:D

Stigkester
Beiträge: 9
Registriert: 02.01.2021, 21:33
System: CCU
Hat sich bedankt: 2 Mal

Re: Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

Beitrag von Stigkester » 21.09.2022, 12:32

Oh ok dann war ich nur zu doof. Alles passt. Danke

Henke
Beiträge: 144
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 39 Mal
Danksagung erhalten: 38 Mal

Re: Script CCU-Auslastung, Temperatur und Load in Systemvariablen schreiben

Beitrag von Henke » 23.09.2022, 04:47

Vielleicht sollte ich in die Info etwas in der Art einbauen.
Temperatur zu hoch -> mir ist warm...und ich muss arbeiten

Fände ich witzig. Besser als die trockenen Warnungen, wie am WE im Kino mit Windows Bluescrenn auf der Werbetafel.

Antworten

Zurück zu „HomeMatic IP mit CCU“