Script für gleitenden Mittelwert

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

Moderator: Co-Administratoren

MichaelN
Beiträge: 9650
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 697 Mal
Danksagung erhalten: 1617 Mal

Re: Script für gleitenden Mittelwert

Beitrag von MichaelN » 01.01.2023, 20:19

Chemieka hat geschrieben:
01.01.2023, 20:02
Nein stimmt es ist Kanal 1 und damit muss dort 001818A992BC16:1 rein.
Da fehlt Dir ein grundlegendes Verständnis für symbolische Bezeichner. Der Kanalname von Kanal 1 ist nicht 001818A992BC16:1, zumindest nicht laut Screenshot und der KAnalname setzt sich lt. Skript immer noch wie folgt zusammen:
Chemieka hat geschrieben:
01.01.2023, 20:02
dom.GetObject(raum#".001818A992BC16:1")
Solange Du die Hinweise nicht genauer befolgst, wird das nichts werden. Nochmal: Du musst den Kanal umbenennen.
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

Chemieka
Beiträge: 649
Registriert: 03.01.2017, 17:39
Hat sich bedankt: 4 Mal
Danksagung erhalten: 9 Mal

Re: Script für gleitenden Mittelwert

Beitrag von Chemieka » 01.01.2023, 20:47

Ich habe den Datenpunkt jetzt umgeschrieben, leider noch immer nicht.

Code: Alles auswählen

 ! Liste initialisieren
string raum = "Aussen";
integer n = 24;
string x = dom.GetObject(raum#".WetterstationTemp").DPByHssDP("TEMPERATURE").Value().ToString(1); 
string list = x;
integer i = 1;
while(i < n)
{list = list#","#x;
 i = i + 1;
}
dom.GetObject(raum#"TListe").State(list);
EFDC0032-94EB-4786-8E9C-84456B493C7E.jpeg
PI3+ mit RaspberryMatic; PI4 mit IOBroker; Samsung Tab A mit Mediola Visualisierung; Harmony Hub; Philips Hue; Drei IP Cams; Zwei Leseköpfe an den Stromzählern; Reedkontakt (Arduino) am Wasserzähler; Drucksensor (Arduino); CUL433 für Intertechno und Somfy RTS; Nuki Bridge

Benutzeravatar
Henke
Beiträge: 1521
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 140 Mal
Danksagung erhalten: 306 Mal

Re: Script für gleitenden Mittelwert

Beitrag von Henke » 01.01.2023, 21:13

raum#".WetterstationTemp" == "Aussen.WetterstationTemp"

Vorhanden ist: "WetterstationTemp"

also

dom.GetObject("WetterstationTemp").DPByHssDP("TEMPERATURE").Value().ToString(1);

Chemieka
Beiträge: 649
Registriert: 03.01.2017, 17:39
Hat sich bedankt: 4 Mal
Danksagung erhalten: 9 Mal

Re: Script für gleitenden Mittelwert

Beitrag von Chemieka » 01.01.2023, 21:29

Dachte das ist der Raum wo der Sensor zugeordnet ist.
Aber das ist nicht das Problem scheinbar.
Die Variable AussenTListe und AussenMittel werden nicht beschrieben.

Code: Alles auswählen

 ! Liste initialisieren
string raum = "Aussen";
integer n = 24;
string x = dom.GetObject("WetterstationTemp").DPByHssDP("TEMPERATURE").Value().ToString(1); 
string list = x;
integer i = 1;
while(i < n)
{list = list#","#x;
 i = i + 1;
}
dom.GetObject(raum#"TListe").State(list);
PI3+ mit RaspberryMatic; PI4 mit IOBroker; Samsung Tab A mit Mediola Visualisierung; Harmony Hub; Philips Hue; Drei IP Cams; Zwei Leseköpfe an den Stromzählern; Reedkontakt (Arduino) am Wasserzähler; Drucksensor (Arduino); CUL433 für Intertechno und Somfy RTS; Nuki Bridge

MichaelN
Beiträge: 9650
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 697 Mal
Danksagung erhalten: 1617 Mal

Re: Script für gleitenden Mittelwert

Beitrag von MichaelN » 01.01.2023, 21:33

Was steht denn im Fehlerprotokoll?
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

Chemieka
Beiträge: 649
Registriert: 03.01.2017, 17:39
Hat sich bedankt: 4 Mal
Danksagung erhalten: 9 Mal

Re: Script für gleitenden Mittelwert

Beitrag von Chemieka » 01.01.2023, 21:37

Das muss ich mir mal anschauen. Mom.

ja mei ACTUAL_TEMPERATURE muss da rein. Gibts doch nicht.

Code: Alles auswählen

 ! Liste initialisieren
string raum = "Aussen";
integer n = 24;
string x = dom.GetObject("WetterstationTemp").DPByHssDP("ACTUAL_TEMPERATURE").Value().ToString(1); 
string list = x;
integer i = 1;
while(i < n)
{list = list#","#x;
 i = i + 1;
}
dom.GetObject(raum#"TListe").State(list);
Danke euch für die Unterstützung
PI3+ mit RaspberryMatic; PI4 mit IOBroker; Samsung Tab A mit Mediola Visualisierung; Harmony Hub; Philips Hue; Drei IP Cams; Zwei Leseköpfe an den Stromzählern; Reedkontakt (Arduino) am Wasserzähler; Drucksensor (Arduino); CUL433 für Intertechno und Somfy RTS; Nuki Bridge

MichaelN
Beiträge: 9650
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 697 Mal
Danksagung erhalten: 1617 Mal

Re: Script für gleitenden Mittelwert

Beitrag von MichaelN » 02.01.2023, 16:58

ALso das ganze geht IMHO einfacher - hier mein komplett selbst-konfigurierendes Skript:

WebUI Programm anlegen, das von dem zu mittelnden Datenpunkt getriggert wird. Dieser Datenpunkt muss einen Wert für .Value() liefern:
Unbenannt.JPG
In diesem Beispiel wird die Berechnung bei jeder Aktualisierung von FBH_temp_0 oder FBH_temp_1 angestoßen und der Mittelwert dafür in aa_FBH_temp_0_MW bzw aa_FBH_temp_1_MW gespeichert.

Wichtig ist die Bedingung so zu formulieren, das bei jeder Aktualisierung des Messwertes das Programm getriggert wird. Es können beliebig viele Trigger (mit ODER verknüpft) aufgeführt werden, da der Name der Systemvariable mit dem Ergebnis dynamisch aus dem triggernden Objekt berechnet wird.

Alternativ: Programm regelmäßig von einem Zeitmodul triggern lassen - z.B. Jede Stunde mit n=24 für einen Tagesdurchschnitt.
Wichtig: dann muss die erste Bedingung des Programms den Datenpunkt/Systemvariable enthalten, der gemittelt werden soll - aber mit "nur prüfen" - der soll ja nicht das Programm triggern.
Man kann sogar beide Varianten kombinieren und in weiteren Bedingungen das Programm von Datenpunkten triggern lassen - diese werden dann bei Aktualisierung gemittelt - unabhängig vom Zeitmodul. Wichtig: die Bedingungen ver-ODER-n, so das sie immer erfüllt sind.
Unbenannt2.JPG
In diesem Beispiel wird die Berechnung für sonne_elevation vom Zeitmodul angestoßen und in aa_sonne_elevation_MW gespeichert, sowie bei jeder Aktualisierung von FBH_temp_1 wird der Mittelwert dafür in aa_FBH_temp_1_MW gespeichert.

Dann dieses Skript einfügen. Das einzige was man im Skript konfigurieren muss ist ggf. Suffix und Prefix, sowie auf jedenfall den Wert n, der bestimmt aus wievielen Werten der Mittelwert gebildet wird.
Es wird das Ergebnis in eine Systemvariable geschrieben, die aus Prefix + Objekt-Name + Suffix gebildet wird. Im Beispiel heißt das Objekt FBH_Temp_1. Die SV wird dann aa_FBH_Temp_1_MW heißen. Existiert diese SV nicht, wird sie angelegt.
Setzt man bDebug auf true kann man im Fehlerprotokoll Log-Daten des Skript finden.

Code: Alles auswählen

! gleitenden Mittelwert aus triggerndem Wert berechnen
! V1.1 MichaelN https://homematic-forum.de/forum/viewtopic.php?f=43&t=10182&p=750572#p750572
! GPL-3.0-or-later
! triggern durch zu mittelnden Datenpunkt/SV oder Zeitmodul - dann muss der zu mittelnde DP/SV in der erste Bedingung stehen (auf nur prüfen)

! gespeichert wird in Systemvariable aus Prefix + Name + Suffix
string Prefix = "aa_";
string Suffix = "_MW";
real n = 24.0; 			! Anzahl der Werte aus denen der Mittelwert gebildet wird - wichtig mit .0
boolean bDebug = false;	! true für Debugging Infos im Fehlerprotokoll

! ab hier nichts mehr ändern
object oPrg = dom.GetObject("$this$");
string Skriptname = oPrg.Name();
string s_text; string s_out; string s_err; string SVName ="";

if (bDebug) {
    	s_text = "+++ START";
		system.Exec("logger -t "#Skriptname#" -p user.debug "#s_text, &s_out, &s_err);
}

integer iSrcId = ("$src$").ToInteger();
if (!iSrcId ) { quit; }

object oSrc = dom.GetObject(iSrcId);
if (!oSrc) { quit; }

if(oSrc.TypeName() == "CALENDARDP")
	{
    ! Auslöser ist Zeitmodul
    ! Datenpunkt ermitteln
	integer iCondition = 0; !Nummer der Condition
	integer iSingle = 0; !Nummer der SingleCondition
	object oCND; object oSCND;
	object oRULE= oPrg.Rule ();
	oCND=oRULE.RuleCondition(iCondition); ! Condition
	oSCND=oCND.CndSingleCondition(iSingle);
	oSrc = dom.GetObject(oSCND.LeftVal());
 	if (bDebug) {
	  s_text = "Auslöser ist Zeitmodul - DP ist:" # oSrc.Name();
	  system.Exec("logger -t "#Skriptname#" -p user.debug "#s_text, &s_out, &s_err);
	 }
	SVName = Prefix # oSrc.Name() # Suffix;
    } else {
    ! Auslöser ist Datenpunkt oder SV
	if (bDebug) {
	  s_text = "Auslöser ist DP oder SV:" # oSrc.Name();
	  system.Exec("logger -t "#Skriptname#" -p user.debug "#s_text, &s_out, &s_err);
	 }
    SVName = Prefix # oSrc.Name() # Suffix;
    }

if (bDebug) {
	s_text = "speichern in : " #SVName;
	system.Exec("logger -t "#Skriptname#" -p user.debug "#s_text, &s_out, &s_err);
}

object MittelwertSV = dom.GetObject (ID_SYSTEM_VARIABLES).Get (SVName);


if (!MittelwertSV) {
    s_text = "Erstelle SV: " # SVName;
	system.Exec("logger -t "#Skriptname#" -p user.debug "#s_text, &s_out, &s_err);
    MittelwertSV = dom.CreateObject(OT_VARDP, SVName);
    object svObjects = dom.GetObject(ID_SYSTEM_VARIABLES);
    svObjects.Add(MittelwertSV.ID());
    MittelwertSV.ValueType(ivtFloat);
    MittelwertSV.ValueSubType(istGeneric);
    MittelwertSV.DPInfo("Script " # Skriptname # " Result - Variable nicht umbenennen");
    MittelwertSV.ValueUnit('');
    MittelwertSV.State(oSrc.Value().ToFloat());
    MittelwertSV.Internal(false);
    MittelwertSV.Visible(true);
    dom.RTUpdate(0);
}

real Messung = oSrc.Value().ToFloat();
real MW = MittelwertSV.Value();
if (bDebug) {
	s_text = "Startwert: "#MW;
	system.Exec("logger -t "#Skriptname#" -p user.debug "#s_text, &s_out, &s_err);
	s_text = "Messwert: "#Messung;
	system.Exec("logger -t "#Skriptname#" -p user.debug "#s_text, &s_out, &s_err); 
}
MW =  (MW * ((n-1.0)/n)) + (Messung / n);
MW = MW.Round(3);
MittelwertSV.State(MW);
if (bDebug) {
	s_text = "Neuer Wert: "#MW;
	system.Exec("logger -t "#Skriptname#" -p user.debug "#s_text, &s_out, &s_err);
}
if (bDebug) {
    	s_text = "+++ ENDE";
		system.Exec("logger -t "#Skriptname#" -p user.debug "#s_text, &s_out, &s_err);
}
ChangeLog:
V1.1 Auslösung auch durch Zeitmodul möglich
Zuletzt geändert von MichaelN am 07.01.2023, 17:56, insgesamt 12-mal geändert.
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

Chemieka
Beiträge: 649
Registriert: 03.01.2017, 17:39
Hat sich bedankt: 4 Mal
Danksagung erhalten: 9 Mal

Re: Script für gleitenden Mittelwert

Beitrag von Chemieka » 02.01.2023, 19:27

Hm. Aber das bedeutet unter Umständen, wenn der Wert gleich bleibt eine Zeit lang. Hast du nur einen Wert aufgenommen. Ändert dich der Wert recht schnell, hast du viele Werte aufgenommen. Denke der Tagesdurchschnitt wäre nicht sonderlich genau.
Man sollte schon immer im gleichen Abstand den Temperaturwert abfragen.

Hoffe ich verstehe das richtig.

Hätte jetzt die obere Variante und denke das läuft.
PI3+ mit RaspberryMatic; PI4 mit IOBroker; Samsung Tab A mit Mediola Visualisierung; Harmony Hub; Philips Hue; Drei IP Cams; Zwei Leseköpfe an den Stromzählern; Reedkontakt (Arduino) am Wasserzähler; Drucksensor (Arduino); CUL433 für Intertechno und Somfy RTS; Nuki Bridge

MichaelN
Beiträge: 9650
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 697 Mal
Danksagung erhalten: 1617 Mal

Re: Script für gleitenden Mittelwert

Beitrag von MichaelN » 02.01.2023, 19:48

Ja, du hast das Problem richtig erkannt. Für viele Anwendungen, wo man nur einen "beruhigten" Messwert benötigt aber ausreichend. Für Tages/Monats oder sonstige zeitbasierten Mittelwerte natürlich problematisch.

EDIT: Daher habe ich das Skript nochmal aktualisiert. Es kann nun auch zeitlich getriggert werden.
Zuletzt geändert von MichaelN am 07.01.2023, 13:07, insgesamt 1-mal geändert.
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

Chemieka
Beiträge: 649
Registriert: 03.01.2017, 17:39
Hat sich bedankt: 4 Mal
Danksagung erhalten: 9 Mal

Re: Script für gleitenden Mittelwert

Beitrag von Chemieka » 05.01.2023, 22:41

Musste das Programm erstmal wieder rausnehmen die CCU hing sich immer wieder auf.
Muss mal noch etwas testen, muss aber irgendwie mit dem Script zusammenhängen. Leider.
PI3+ mit RaspberryMatic; PI4 mit IOBroker; Samsung Tab A mit Mediola Visualisierung; Harmony Hub; Philips Hue; Drei IP Cams; Zwei Leseköpfe an den Stromzählern; Reedkontakt (Arduino) am Wasserzähler; Drucksensor (Arduino); CUL433 für Intertechno und Somfy RTS; Nuki Bridge

Antworten

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