nächste Ausbaustufe
Dieses Skript speichert das Ergebnis zwischen und gibt dann zusätzlich eine Liste der Programme mit Häufigkeit seit dem ersten Programmlauf aus.
Wenn man ein kleines Programm erstellt, das alle 121 Sekunden aufgerufen wird und dieses Skript mit 120 Sekunden Schwellwert einfügt, dann hat man nach kurzer Zeit einen Überblick über die verdächtigen Kandidaten. Das aufrufende Programm sollte an erster Stelle mit der Anzahl der Programmdurchläufe gelistet sein. Das Ergebnis sieht dann so aus:
Code: Alles auswählen
=== wie häufig getriggert: xxxTest:13x === PGM_Sonnenstand:9x === PGM_Schatten-Level:5x === PGM_CS-Alarm:5x === Tuer_offen_pruefen:2x === PGM_Nachricht_Tuer_offen:1x === PGM_Hide-FW-Updates:1x ===
Dazu muss man im Skript-Code den Namen der Text-Variablen angeben, die als Zwischenspeicher dient!
string SVName = "xxx";
Und man gibt den Namen einer Text-Variablen an, die auf "protokolliert" steht.
string Logs = "xxx";
Dann findet man das Ergebnis im Systemprotokoll wieder.
Ansonsten steht das Ergebnis nur in der SV zum zwischenspeichern - oder wird ausgegeben wenn man das Skript unter "Skript testen" ausführt.
Man kann den Code natürlich auch weiterhin nur über "Skript testen" ausführen. Die Zwischenspeicher-SV muss man aber in jeden Fall anlegen!
Will man wieder bei "Null" starten - oder enthält die SV noch alte Inhalte, dann muss man die Zwischenspeicher-SV leeren:
Code: Alles auswählen
string SVName = "xxTest"; ! Name der Systemvariablen (Typ Text) zum Zwischenspeichern
dom.GetObject(ID_SYSTEM_VARIABLES).Get(SVName).State("");
Hier das Skript:
Code: Alles auswählen
! Listet alle Programme, die in den letzten x Minuten getriggert wurden V2.3
! MichaelN https://homematic-forum.de/forum/viewtopic.php?f=31&t=68913&p=673244#p673252
! GPL-3.0-or-later
integer Schwelle = 2*60; ! Hier die Anzahl x Minuten einstellen
string SVName = "xxTest"; ! Name der Systemvariablen (Typ Text) zum Zwischenspeichern
string Logs = "Protokolleintrag"; ! Name der Systemvariablen (Typ Text) zum Protokollieren
string OutputTrenner;
OutputTrenner = "=== "; ! Wie soll die Auflistung formatiert werden? In einer Zeile
OutputTrenner = "\n"; ! Oder lieber untereinander - unerwünschtes auskommentieren
string ListTrenner =","; ! Zeichen zum Trennen der Listeneinträge - darf nicht mit Sonderzeichen im Programmnamen kollidieren
! === hier nix mehr aendern ===
string i; string j; string SVtemp;
object o; object SV;
string slist = ""; string output = ""; string slist_neu ="";
string PName;
integer Last;
integer Jetzt = system.Date("%F %T").ToTime().ToInteger();
integer Diff;
integer Zaehler = 0;
string j_Name; integer j_Zaehler;
foreach(i, dom.GetObject(ID_PROGRAMS).EnumUsedIDs()) {
o = dom.GetObject (ID_PROGRAMS).Get (i);
Last = o.ProgramLastExecuteTimeSeconds();
Diff = Jetzt - Last;
if ( Diff < Schwelle )
{
PName = o.Name();
slist = o#ListTrenner#slist;
WriteLine (PName#" - "#Diff);
}
}
SV = dom.GetObject(ID_SYSTEM_VARIABLES).Get(SVName);
if (slist && SV)
{
output = "=== wie häufig getriggert: "#OutputTrenner;
SVtemp = SV.Value();
foreach(i, slist.Split(ListTrenner)) {
if (!SVtemp) {
! Liste leer, neu aufbauen
output = output#i#":1x "#OutputTrenner;
slist_neu = slist_neu#i#";1"#ListTrenner;
} else {
j_Zaehler = 0;
if ( SVtemp.Contains(i) ) {
foreach(j, SVtemp.Split(ListTrenner)) {
j_Name = web.webGetValueFromList(j,0);
j_Zaehler = web.webGetValueFromList(j,1).ToInteger();
if (i == j_Name) {
j_Zaehler = j_Zaehler + 1;
output = output#j_Name#":"#j_Zaehler#"x "#OutputTrenner;
slist_neu = slist_neu#j_Name#";"#j_Zaehler#ListTrenner;
}
}
} else {
! Eintrag neu
slist_neu = slist_neu#i#";1"#ListTrenner;
output = output#i#":1x "#OutputTrenner;
}
}
}
foreach(j, SVtemp.Split(ListTrenner)) {
j_Name = web.webGetValueFromList(j,0);
j_Zaehler = web.webGetValueFromList(j,1).ToInteger();
if ( !slist_neu.Contains(j_Name) ) {
! Eintrag unverändert übernehmen
output = output#j_Name#":"#j_Zaehler#"x "#OutputTrenner;
slist_neu = slist_neu#j_Name#";"#j_Zaehler#ListTrenner;
}
}
SV.State(slist_neu);
WriteLine(output);
SV = dom.GetObject(ID_SYSTEM_VARIABLES).Get(Logs);
if (SV) { SV.State(output); }
}
V2.3
man kann jetzt zusätzlich einstellen, welche Zeichen zum Trennen der Listeneinträge benutzt werden.
Zum einen für den Output. Hier sind 2 Varianten vordefiniert um eine einzeilige oder mehrzeilige Ausgabe zu erhalten. Einfach die ungewünschte Variante mit ! am Zeilenanfang auskommentieren
Zum anderen für die Zwischenspeicherung. Standardmäßig ist hier das "," eingestellt. Benutzt man das Komma auch in Programmnamen, funktioniert das Skript nicht mehr richtig. Dann kann man für ListTrenner ein anderes Zeichen eintragen. "&" ist erprobt. Was man nicht nehmen sollte ist das ";". Das brauche ich für andere Zwecke und das habe ich jetzt nicht auch noch parametrisierbar gemacht. Generell ist - eben aus solchen Gründen - der Einsatz von Sonderzeichen in Programm- oder anderen Objektnamen nicht empfehlenswert.