Auslöser eines Programmes finden und loggen

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

alchy
Beiträge: 10752
Registriert: 24.02.2011, 01:34
System: CCU
Hat sich bedankt: 65 Mal
Danksagung erhalten: 672 Mal

Auslöser eines Programmes finden und loggen

Beitrag von alchy » 15.02.2017, 16:06

Script ist nicht für aktuelle RaspberryMatic Versionen.


In einem anderen Thread hatte ich die Möglichkeit schon gepostet, wie man den Auslöser eine zusammengeklicktem Programmes herausfindet.
Um die Übersicht zu wahren und weil ich das Script einwenig weiter entwickelt habe, hier eine zusammenfassende Anleitung unter Tipps & Tricks
Ich hoffe es ist würdig genug.

Neu in 0.99
  • Bug beseitigt, wenn der Wert des Auslösers innerhalb des Programms vor Ausführung des Scriptes geändert wurde
  • Danke an BadenPower für die Mail
Erklärung:
Gerade, wer nicht so richtig mit der Logik der Programme zu Recht kommt, oder wer sich über mysteriöse Auslösungen seiner zusammengeklickten Programme wundert, erhält hier eine Möglichkeit seine Programme zu überprüfen. Da das Script auch den namen des Programmes mitloggt, kann man natürlich nicht nur ein Programm auf die Art überprüfen. Die Systemvariable bleibt dieselbe, einfach das Script in ein weiteres Programm einfügen.
Leider lässt die Klickibunti keine Filterung an der Stelle zu. Aber die Exportierenfunktion eröffnet da viele Wege.

Benutzung:
1. wir legen ein Systemvariable Typ: Zeichenkette an mit dem Namen: Programme_loggen in der Klickibunti an
2. wir benutzen den Haken protokolliert bei dieser Systemvariable
programmloggen_sysvar.jpg
Protokollieren anhaken nicht vergessen

3. Wir fügen das nachfolgende Script in irgendeinen Programmablauf ein, den wir protokolliert haben wollen. Dabei ist es völlig unerheblich, was da so als möglicher Auslöser des Programmes zusammengeklickt wurde.
Nur zur Verdeutlichung habe hier ein sinnloses Programm zusammengeklickt:
die Zeile
string slist = " DANN ";
sollte noch auf
string slist = " SONST ";

angepasst werden, wenn man das Script im SONST bzw. im DANN eines Programmes einbaut. Man sollte es auch in allen Zweigen einbauen.


programmloggen_prog.jpg
ziemlich sinnloses Programm nur zur Verdeutlichung
4. Am Script sind keine Änderungen ausser oberhalb ++++ Finger weg +++++ nötig - kopieren - einfügen - fertig

Code: Alles auswählen

! mit Programmname, Auslöser, Auslösewert und (Einheit falls vorhanden) und Zeit in Stringvariable schreiben
! v 1.00 (c) by alchy 
! https://homematic-forum.de/forum/viewtopic.php?f=31&t=35686
! +++++++++++++++++
string slist = " DANN ";
string sysvarOut = "Programme_loggen"; ! Name Systemvariable Typ Zeichenkette zum Speichern der Ausgabe - auf Protokolliert stellen = Speicherung im Systemprotokoll
string sThis = "$this$";string sSrc = "$src$";string sVal = "$val$";object oThisPrg;object oSrc;string oSrcValue =" unbekannt";
if((sThis <> "") && (sThis <> "$" # "this" # "$")){
  slist = slist # "Prg-ID: " # sThis; oThisPrg = dom.GetObject(sThis);
 if(oThisPrg)  {
  if(oThisPrg.Type() == OT_PROGRAM)  {
     slist = slist # " / Prg-Name: " # oThisPrg.Name();
    }else{ slist = slist # " / Prg durch anderes Objekt ersetzt";}
  }else{ slist = slist # " / Prg geloescht"; }
if((sSrc <> "") && (sSrc <> "$" # "src" # "$")) {
    slist = slist # " / Src-ID: " # sSrc;
    oSrc = dom.GetObject(sSrc);
    if(oSrc){ slist = slist # " / Src-Name: " # oSrc.Name();
	}else{ slist = slist # " / Src geloescht"; }
slist = slist # " / Wert: " # sVal #" = "#oThisPrg.Name() #" ";
if(oSrc.TypeName() == "HSSDP") {
   if ( (oSrc.ValueTypeStr() == "Float") || (oSrc.ValueTypeStr() == "Scaling") ) {oSrcValue = (sVal).ToString(2) #" "#oSrc.ValueUnit();}
   if ( (oSrc.HssType() == "PRESS_SHORT") || (oSrc.HssType() == "PRESS_LONG") ) {  oSrcValue = oSrc.HssType();}
   if (oSrc.HssType() == "MOTION") {   if (sVal == "1") { oSrcValue = "Bewegung erkannt"; } elseif (sVal == "0") {oSrcValue ="keine Bewegung";} }
   if ( (oSrc.ValueTypeStr() == "Binary") && (dom.GetObject(((dom.GetObject(oSrc)).Channel())).HssType() == "SHUTTER_CONTACT") ) {
   if (sVal == "1") { oSrcValue = "offen"; } elseif (sVal == "0") {oSrcValue ="geschlossen";} }
   if (oSrc.ValueTypeStr() == "Binary") { if (sVal == "1") { oSrcValue = "ein"; } elseif (sVal == "0") {oSrcValue ="aus";} }
   if (oSrc.ValueTypeStr() == "Integer") {oSrcValue = (sVal) #" "#oSrc.ValueUnit();}
   if ( (oSrc.ValueTypeStr() == "Integer") && (dom.GetObject(((dom.GetObject(oSrc)).Channel())).HssType() == "SHUTTER_CONTACT") ) {
   if (sVal == "1") { oSrcValue = "offen"; } elseif (sVal == "0") {oSrcValue ="geschlossen";} }
   if ( (oSrc.ValueTypeStr() == "Integer") && (dom.GetObject(((dom.GetObject(oSrc)).Channel())).HssType() == "ROTARY_HANDLE_SENSOR") ) {
   if (sVal == "0" ) { oSrcValue = "geschlossen"; }
   if (sVal == "1" ) { oSrcValue = "gekippt"; }
   if (sVal == "2" ) { oSrcValue = "offen"; } }
   if (  (dom.GetObject(((dom.GetObject(oSrc)).Channel())).HssType() == "WATERDETECTIONSENSOR") || (dom.GetObject(((dom.GetObject(oSrc)).Channel())).HssType() == "WATER_DETECTION_TRANSMITTER") ) {
   if (sVal == "0" ) { oSrcValue = "trocken"; }
   if (sVal == "1" ) { oSrcValue = "feucht"; }
   if (sVal == "2" ) { oSrcValue = "nass"; } }
   if ( (dom.GetObject(((dom.GetObject(oSrc)).Channel())).HssType() == "HEATING_CLIMATECONTROL_TRANSCEIVER") || (dom.GetObject(((dom.GetObject(oSrc)).Channel())).HssType() == "CLIMATECONTROL_RT_TRANSCEIVER") || (dom.GetObject(((dom.GetObject(oSrc)).Channel())).HssType() == "THERMALCONTROL_TRANSMIT") ){
   if (sVal == "0" ) { oSrcValue = "AUTO"; }
   if (sVal == "1" ) { oSrcValue = "MANU"; }
   if (sVal == "2" ) { oSrcValue = "URLAUB"; } 
   if (sVal == "3" ) { oSrcValue = "BOOST"; }}
    slist = slist #"Geraet: "#(dom.GetObject((dom.GetObject(dom.GetObject(oSrc).Channel())).Device())).Name() #" durch Kanal: " #(dom.GetObject(dom.GetObject(oSrc).Channel())).Name() #" "#(dom.GetObject(dom.GetObject(oSrc).Channel())).HssType() #" mit DP: "#oSrc.HssType() #" und dem Wert: "#oSrcValue #" am: "#system.Date("%d.%m. %H:%M Uhr");
}elseif(oSrc.TypeName() == "VARDP") {
   if (oSrc.ValueType() == ivtBinary) { oSrcValue = oSrc.ValueName() ;} 
   if (oSrc.ValueSubType() == istGeneric) {oSrcValue = (sVal).ToString(1)#" "#oSrc.ValueUnit(); if (sVal == "") { oSrcValue = "0"; }}
   if (oSrc.ValueSubType() == istEnum) { oSrcValue = web.webGetValueFromList(oSrc.ValueList(),sVal)#" "#oSrc.ValueUnit();}
   if (oSrc.ValueSubType() == istChar8859) {oSrcValue = sVal;}
   slist = slist #" durch Systemvariable: " #oSrc.Name()#" mit dem Wert: "#oSrcValue;
  }
  elseif ( (oSrc.TypeName() == "ALARMDP") &&  (oSrc.ValueType() == ivtBinary) ) { oSrcValue = oSrc.ValueName() ;
  slist = slist #" durch Alarm: " #oSrc.Name()#" mit dem Wert: "#oSrcValue #" am: "#system.Date("%d.%m. %H:%M Uhr");
  }elseif(oSrc.TypeName() == "CALENDARDP"){
  if (oSrc.ValueTypeStr() == "Binary") { if ( sVal )  { oSrcValue = "Zeitpunkt erreicht"; }else{ oSrcValue = "Zeitpunkt nicht erreicht";}}
  slist = slist #" durch: " #oSrc.Name()#" mit dem Wert: "#oSrcValue #" am: "#system.Date("%d.%m. %H:%M Uhr");
  }
  }else{
    slist = slist # " / kein Ausloeser";
    if(sVal == ""){ slist = slist # " = nach CCU-Reboot (ReGaHss Neustart) oder durch Aktivieren gestartet"; }
    else{
      if(sVal == "1") {  slist = slist # " = manuell oder per .ProgramExecute() oder per .State(1) gestartet";}
      else{ slist = slist # " = Wert: " # sVal;}
    }
    slist = slist # " = " # sVal;
  }
}else{
  slist = "Das Script: Programmausloeser egal welchen Types... wurde nicht in einem Programm ausgefuehrt am: "#system.Date("%d.%m. %H:%M Uhr");
  WriteLine(slist);
}
if ( (dom.GetObject(ID_SYSTEM_VARIABLES)).Get(sysvarOut) ) { dom.GetObject(ID_SYSTEM_VARIABLES).Get(sysvarOut).State( slist ); }
}
5. wir schauen dann irgendwann im Systemprotokoll nach, was, wann welches Programm ausgelöst hat und warum
programmloggen_ergebnis.jpg
das Ergebnis im Systemprotokoll

Erweiterung

will man die Ausgabe des Scriptes z.B. um die Versendung der Ausgabe per Telegramm erweitern, hängt man einfach ganz am Ende des Scriptes noch folgende Zeilen an:

Code: Alles auswählen

! Versand über Telegram mit wget und system.exec
string chatid = "xxxxxxxxx";
string botAPI = "XXXXXXXXXXXXXXXXXXXXXXX";
var url = "https://api.telegram.org/bot"#botAPI#"/sendMessage?chat_id="#chatid#"&parse_mode=html&text="#slist.ToUTF8();
system.Exec("wget -q -O - '"#url#"' &");
oder pushover

Code: Alles auswählen

! Versand über Pushover mit wget und system.exec 
var USERKEY = "xxxxxxxxxxxxxxxxxxxx";
var TOKEN = "XXXXXXXXXXXXXXXX";
system.Exec("wget --no-check-certificate --post-data 'token='"#TOKEN#"'&user='"#USERKEY#"'&message="#slist.ToLatin().UriEncode() #"' -O - https://api.pushover.net/1/messages" );

oder eben auch per mail

Code: Alles auswählen

if(slist!="")  { dom.GetObject(ID_DATAPOINTS).Get("CUxD.CUX2801001:1.CMD_EXEC").State("/etc/config/addons/email/email 01 '"#slist# "'"); }
bzw.

Code: Alles auswählen

system.Exec("/etc/config/addons/email/email 01"#" &");
^^ Grund voraussetzung dafür ist natürlich erstmal, das das >>Mailaddon<< installiert ist und funktioniert

UND

das im TCL Reiter die folgende Zeile

Code: Alles auswählen

set serviceliste [encoding convertfrom utf-8 [lindex $argv 1]]
oben eingefügt wird, sowie in der Mailvorlage der Wahl dann steht:

Code: Alles auswählen

Mit Parameter vom Script übergeben:

$serviceliste

usw.

Alchy
Zuletzt geändert von alchy am 14.08.2020, 23:26, insgesamt 19-mal geändert.

Blacklist................... almost full
Ignoranz ist die Summe aller Maßnahmen die man ergreift, um bestehende Tatsachen nicht sehen zu müssen.

© Sandra Pulsfort (*1974)

Lies bitte die Logik von WebUI Programmen und die Tipps und Tricks für Anfänger.

Wichtig auch CUxD ersetzt System.exec. Die HM Script Doku (Downloadart Skripte) hilft auch weiter.
Zum Testen von Scripten den >> HomeMatic Script Executor << von Anli benutzen.

Benutzeravatar
Herbert_Testmann
Beiträge: 11062
Registriert: 17.01.2009, 11:30
Danksagung erhalten: 7 Mal

Re: Auslöser eines Programmes finden und loggen

Beitrag von Herbert_Testmann » 15.02.2017, 17:36

sehr nützlich.

Danke
---
Dieses Schreiben wurde maschinell erstellt und ist ohne Unterschrift gültig

Dax
Beiträge: 93
Registriert: 08.02.2016, 17:32
Danksagung erhalten: 1 Mal

Re: Auslöser eines Programmes finden und loggen

Beitrag von Dax » 17.02.2017, 08:41

Wow super - vielen Dank!

darkiop
Beiträge: 143
Registriert: 22.11.2013, 10:53

Re: Auslöser eines Programmes finden und loggen

Beitrag von darkiop » 19.03.2017, 08:58

Guten Morgen, bin heute beim frühstücken auf den Gedanken gekommen die Programm welche ausgeführt werden ins Log zu schreiben. Kurz im Forum gesucht, eingebunden - funktioniert :)

Vielen Dank Alchy!!
Gruß Thorsten

fischmir
Beiträge: 972
Registriert: 03.02.2014, 18:04
Wohnort: Münsterland
Hat sich bedankt: 27 Mal
Danksagung erhalten: 8 Mal

Re: Auslöser eines Programmes finden und loggen

Beitrag von fischmir » 19.03.2017, 19:57

Klasse, danke!

Möchte nur zu bedenken geben, dass bei einer Umstellung auf tmp die folgende Zeile weh tut:

Code: Alles auswählen

object src = dom.GetObject("$src$");
Typischerweise würde das zu

Code: Alles auswählen

object tmpA = dom.GetObject("$tmpA$");
...ersetzt werden, was dann natürlich nicht mehr funktioniert.

Vielleicht die Variable zukünftig src zu lsrc umbennenen?

Viele Grüße,
Christian

fischmir
Beiträge: 972
Registriert: 03.02.2014, 18:04
Wohnort: Münsterland
Hat sich bedankt: 27 Mal
Danksagung erhalten: 8 Mal

Re: Auslöser eines Programmes finden und loggen

Beitrag von fischmir » 21.03.2017, 09:38

Hallo alchy,

eine Frage habe ich noch - auch wenn ich sehr fest davon ausgehe, dass deine Antwort negativ ausfällt.

Neben der Protokollierung der Programme, protokolliere ich auch (manuell), welcher WENN-DANN-SONST - Teil ausgeführt wird. Kann man dieses auch programmatisch, dynamisch per Script loggen?

Gruß,
Christian

alchy
Beiträge: 10752
Registriert: 24.02.2011, 01:34
System: CCU
Hat sich bedankt: 65 Mal
Danksagung erhalten: 672 Mal

Re: Auslöser eines Programmes finden und loggen

Beitrag von alchy » 21.03.2017, 17:19

fischmir hat geschrieben:auch wenn ich sehr fest davon ausgehe, dass deine Antwort negativ ausfällt.
Wie kommst du denn darauf? :shock:
Aber vielleicht habe ich das auch nur nicht verstanden.
Das Script ist ja dazu da, den Auslöser eines Programmes zu loggen.
Hast du ein verschachteltes Programm mit mehreren Wenn -> dann und Sonst, wenn -> dann usw.
musst du doch nur das Script in alle "Dann" kopieren und fertig.

Alchy

Blacklist................... almost full
Ignoranz ist die Summe aller Maßnahmen die man ergreift, um bestehende Tatsachen nicht sehen zu müssen.

© Sandra Pulsfort (*1974)

Lies bitte die Logik von WebUI Programmen und die Tipps und Tricks für Anfänger.

Wichtig auch CUxD ersetzt System.exec. Die HM Script Doku (Downloadart Skripte) hilft auch weiter.
Zum Testen von Scripten den >> HomeMatic Script Executor << von Anli benutzen.

BadenPower

Re: Auslöser eines Programmes finden und loggen

Beitrag von BadenPower » 21.03.2017, 17:27

alchy hat geschrieben:Aber vielleicht habe ich das auch nur nicht verstanden.
Er möchte nicht den Auslöser ermitteln, sondern welcher Abschnitt des Programmes gerade ausgeführt wird.

Da wäre vielleicht ein Vergleich der .Destinations() und .Conditions() notwendig. Ob es funktioniert kann ich nicht sagen. Müßte ich mir einmal in einer ruhigen Minute zu Gemüte führen.
.

fischmir
Beiträge: 972
Registriert: 03.02.2014, 18:04
Wohnort: Münsterland
Hat sich bedankt: 27 Mal
Danksagung erhalten: 8 Mal

Re: Auslöser eines Programmes finden und loggen

Beitrag von fischmir » 29.03.2017, 18:53

BadenPower hat mich richtig verstanden. Das wäre natürlich erste Sahne, wenn dieses geht.

//Edit: Dan habe ich noch eine weitere Frage:

Ich habe das Programme_loggen nun an einigen Stellen implementiert, aber es spammt mir das Systemprotokoll zu. Daher habe ich mir folgende Logik überlegt.

Code: Alles auswählen

WENN
1. SV_Programm_loggen_aktiv = TRUE
ODER
2. Links($src$, 6) = "Loggen"
ODER
3. InStr ($src$, SV_Programme_loggen_Auswahl)

DANN
loggen.
1. Boolean: Schalter, wenn aktiv, werden alle Programm geloggt
2. Falls nur bestimmte Programm geloggt werden sollen, müssen die umbenannt werden und starten mit "Loggen" (macht natürlich nur Sinn, wenn Boolean-Schalter auf false).
3. Es gibt Programme, die man nicht umbennenen kann ("zPNP" z.B. weil es per Programmnamen von anderso aufgerufen wird). Um diese loggen zu können, muss der Programmname in einer Zeichenkette enthalten sein (hier: SV_Programme_loggen_Auswahl).

Denkst du, dass du diese Logik (oder Teile davon) übernehmen möchtest/ kannst?

Gruß,
Christian
Zuletzt geändert von fischmir am 30.03.2017, 09:08, insgesamt 1-mal geändert.

alchy
Beiträge: 10752
Registriert: 24.02.2011, 01:34
System: CCU
Hat sich bedankt: 65 Mal
Danksagung erhalten: 672 Mal

Re: Auslöser eines Programmes finden und loggen

Beitrag von alchy » 30.03.2017, 08:11

fischmir hat geschrieben:BadenPower hat mich richtig verstanden.
Er hat doch aber etwas ganz anderes geschrieben, als du dann hier so aufführst. :shock:
oder ich kann dir immer noch nicht folgen. :cry:

Den ersten Vorschlag kannst du sehr leicht integrieren. Änderst du die letzte Zeile des Scriptes einfach in

Code: Alles auswählen

!Speichern in Systemvariable, wenn diese protokolliert wird im Systemprotokoll einsehbar
if (((dom.GetObject(ID_SYSTEM_VARIABLES)).Get("SV_Programm_loggen_aktiv")).Value()){ 
((dom.GetObject(ID_SYSTEM_VARIABLES)).Get("Programme_loggen")).State(slist);}
Was den Vorschlag 3 angeht, könnte man eine Systemvariable anlegen, welche die Namen enthält, welche geloggt werden sollen
bzw. bei 2. das Wort loggen als Präfix.
Möglich ist das natürlich.

Alchy

Blacklist................... almost full
Ignoranz ist die Summe aller Maßnahmen die man ergreift, um bestehende Tatsachen nicht sehen zu müssen.

© Sandra Pulsfort (*1974)

Lies bitte die Logik von WebUI Programmen und die Tipps und Tricks für Anfänger.

Wichtig auch CUxD ersetzt System.exec. Die HM Script Doku (Downloadart Skripte) hilft auch weiter.
Zum Testen von Scripten den >> HomeMatic Script Executor << von Anli benutzen.

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“