Script zur Ermittlung eines gleitenden Mittelwertes

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

Moderator: Co-Administratoren

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

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von Henke » 19.05.2023, 23:19

Testen bitte

Code: Alles auswählen

dom.GetObject(svMittelwertGleitend).State(real_Messwert.ToFloat()/2.55);

Marcus1@@@
Beiträge: 219
Registriert: 02.01.2016, 14:24
Danksagung erhalten: 21 Mal

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von Marcus1@@@ » 20.05.2023, 15:08

danke Henke,
aber es klappt nicht.

ich habe in der Werteliste
gemittelte Helligkeit_wl Über 1h gesammelte Werte der Helligkeit. 20.05.2023 15:04:40
208|199|195|216|219|218|162|190|194|203|190|194|192|173|196|189|196|170|162|164
diese Werte stehen

da muss, wenn es funktionieren würde ein Wert von um die 75% rauskommen
in der sysvar steht aber: gemittelte Helligkeit: 193.00 %

ich verstehe es nicht!

Grüße

MichaelN
Beiträge: 9679
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 700 Mal
Danksagung erhalten: 1626 Mal

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von MichaelN » 20.05.2023, 15:49

Vielleicht solltest Du dein Knozept nochmal genauer erklären.

Dieser code macht, was Du willst:

Code: Alles auswählen

string svMittelwertGleitend = "xxZahl";
real real_GleitenderMittelwert;
real real_Messwert = 25.5;

!in die Systemvariable den Messwert als gleitenden Mittelwert schreiben
real_GleitenderMittelwert = real_Messwert;
dom.GetObject(svMittelwertGleitend).State((real_Messwert/255)*100);
WriteLine(dom.GetObject (ID_SYSTEM_VARIABLES).Get ("xxZahl").Value());  
25.5 wird mit 255 mal genommen und durch 100 geteilt. Am Ende kommt 10 raus und das steht auch in der Systevariablen.

Also WAS steht in real_Messwert wirklich?
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 +++

Marcus1@@@
Beiträge: 219
Registriert: 02.01.2016, 14:24
Danksagung erhalten: 21 Mal

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von Marcus1@@@ » 20.05.2023, 16:11

ich nutze das script wie aus dem 1. Beitrag!

real_Messwert scheint soweit ich das überblicken kann auch ein string zu sein! In diesem steht der finale Mittelwert der aus der Werteliste gebildet wird.
was mich nur irritiert ist das "dom.GetObject(svMittelwertGleitend)" im Endeffekt als Typ Systemvariable eine Zahl ist, kann man da einen String reinschreiben?

MichaelN
Beiträge: 9679
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 700 Mal
Danksagung erhalten: 1626 Mal

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von MichaelN » 20.05.2023, 16:32

Ich habe das Script nicht vollständig analysiert. Aber beide Werte sind als real definiert, warum sollten es String sein? Aber das kannst Du ja prüfen.

Füge die beiden WriteLine so ein:

Code: Alles auswählen

!in die Systemvariable den Messwert als gleitenden Mittelwert schreiben
real_GleitenderMittelwert = real_Messwert;
WriteLine("Messwert:" # real_Messwert);
WriteLine("Type 3=real; 4=string: " # real_Messwert.VarType());    
Und lass das komplette Skript in "Skript testen" laufen. Dann ablesen, was unten ausgegeben wird.

Und ggf. uns auch verraten :wink:
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 +++

Marcus1@@@
Beiträge: 219
Registriert: 02.01.2016, 14:24
Danksagung erhalten: 21 Mal

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von Marcus1@@@ » 20.05.2023, 17:53

Code: Alles auswählen

!! MittelwertGleitend V0.1
!! Berechnung eines gleitenden Mittelwertes (einfacher gleitender Durchschnitt) ueber eine frei definierbare Anzahl von Werten
!! * ermoeglicht die Aufzeichnung und Berechnung eines gleitenden Mittelwertes fuer eines
!!     beliebigen Kanalnummes eines Geraetes oder eine Systemvariable aus denen die Werte kommen
!! * es findet keine Wichtung der einzelnen Werte statt, 
!! * das Fenster, aus denen der Mittelwert berechnet wird bleibt gleich
!!
!!(c) duralis; zur freien Verwendung
!!
!!
!! Vorbereitung:
!! * in der CCU Anlegen einer Systemvariable vom Typ "Werteliste" anlegen, - automatisch generierten Inhalt so belassen
!! * in der CCU Anlagen einer Systemvariablen vom Typ "Zahl" mit Minimum -31000 und Maximum 31000 anlegen, dies ist der berechnete gleitende Mittelwert
!! * Konfiguration dieses Scriptes (etwas weiter unten) mit dem Namen der beiden soeben angelegten Systemvariablen und den weiteren Angaben
!! * in der CCU in der grafischen Obeflaeche ein Programm fuer Aufruf dieses Scriptes zusammenklicken, dieses angepasste Script angeben, fertig
!!
!! Aufruf:
!! * dieses Script z.B. mit jeder Messwertaufnahme (bei Aktualisierung) vom Sensor starten oder zeitlich z.B. jede Stunde je nach Zweck
!!

! ******* die folgenden Zeilen muessen angepasst werden ******
string svNameWerteliste = "gemittelte Helligkeit_wl";	! Name der Systemvariablen als Werteliste, der als Speicher fuer die interne Berechnung dient (FiFo, Werte, Namen usw.)
! *** Bitte nur in einer der beiden naechsten Zeilen den Inhalt zwischen die Anfuehrungszeichen "" eintragen ***
string str_NameMesswertGeraet = "BidCos-RF.NEQ1100409:1.BRIGHTNESS";		!hier in "" das Geraet angeben von dem der Messwert kommen soll inkl. kompletter Schnittstelle z.B. "BidCos-RF.OEQ1234567:1.WIND_SPEED" ODER ""
string str_NameMesswertSystemvariable = "";									!hier in "" den Namen der Systemvariablen angeben von dem der Messwert kommen soll und NICHT von einem Geraet
! Name der Systemvariable in dem der jeweils berechnete gleitende Mittelwert, also das Ergebnis, abgelegt werden soll
string svMittelwertGleitend = "gemittelte Helligkeit"; 		! Datentyp "Zahl", Wertebereich -31.000 bis +31.000; Name der Variable fuer den abzuspeichernden gleitenden Mittelwert
integer int_SollAnzahlMittelwerte = 20;				! Anzahl von Messwerten aus denen der gleitende Mittelwert berechnet wird (Beispiel 3 bedeutet, aus der aktuellen und den letzten 2 Messwerten wird der Mittelwert berechnet)
													! Mindestens eine 2 als Zahl angeben, sehr grosse Werte sind eigentlich unsinnig und sorgen fuer viel zu hohe CCU Last

!! ********************************************************************************************************************
! ******* ab hier sind keine Anpassungen im Code mehr notwendig ******

object svObjekt;
! interne Variablen
string TrennzeichenDerZeilen = ";"; !das Semikolon dient als Trennzeichen in der Systemvariable(Listvariable) zum trennen der einzelnen Abschnitte
string TrennzeichenWerte = "|";		! das "|" Pipe dient als Trennzeichen zwischen den Messwerten im FiFo Speicher

string str_WertelisteKomplett;				!nimmt die komplette Werteliste auf (FiFo + Konfiguration)
string str_FiFoKomplett;					!nimmt nur die Werte des FiFo auf
string str_FiFoNeu;							!neue Werte die in den FiFo aufgenommen werden sollen
string str_EinSpeicherwert;					!eine Zahl als String aus der Werteliste
integer int_EinSpeicherwert;				!eine Zahl als Zahl aus der Werteliste
real real_Messwert;							!nimmt Werte als Zahl auf - pruefen ob das nicht "real" sein sollte
integer int_IstAnzahlMittelwerteFiFo;		!aktuelle Anzahl der Mittelwerte im FiFo
string str_index;							!Indexvariable fuer foreach
integer int_index;							!Indexvariable als Zahl
real real_GleitenderMittelwert;				!enthaelt die Zwischenberechnung fuer den gleitenden Mittelwert
integer int_DifAnzahlZusatzWerte;			!Anzahl FiFo Plaetze Aenderung, wenn der FiFo in der Groesse veraendert werden muss

!Aufbau Werteliste Variable
! Index 0 -> FiFo Speicher der einzelnen Messwerte, Pipe trennt die einzelnen Messwerte
! Index 1 -> komplette Adresse des Geraetes von dem die Messwerte genutzt werden ODER Name der Systemvariablen dessen Inhalt als Messwerte genutzt werden
! Index 2 -> Name der Systemvariablen in dem der gleitenden Mittelwert bei jedem Durchlauf geschrieben wird
! Index 3 -> aktuelle Anzahl der Messwerte im FiFo Speicher


!++++++++++++++++ Messwert aus Geraet oder Systemvariable auslesen +++++++++++++++++++++++++
if (str_NameMesswertSystemvariable!="")
{
	real_Messwert = dom.GetObject(str_NameMesswertSystemvariable).State();	!den Messwert einlesen welcher als Mittelwert genutzt werden soll
}
else
{
	real_Messwert = dom.GetObject(str_NameMesswertGeraet).Value();		!den Messwert einlesen welcher als Mittelwert genutzt werden soll
}

!++++++++++++++++ die Werteliste analysieren +++++++++++++++++++++++++
object svObjekt = (dom.GetObject(ID_SYSTEM_VARIABLES).Get(svNameWerteliste));		!Einlesen Werteliste vorbereiten
str_FiFoKomplett = svObjekt.ValueList().StrValueByIndex(TrennzeichenDerZeilen, 0);

!!wenn Script schon gelaufen ist dann Vorbelegte Werte nutzen ansonsten neue Werte erstellen, Find liefert "-1" wenn Substring nicht gefunden wurde
if (str_FiFoKomplett.Find(TrennzeichenWerte)!=-1)
{
	str_EinSpeicherwert = svObjekt.ValueList().StrValueByIndex(TrennzeichenDerZeilen, 3);		!Index 3 in Werteliste = Anzahl Werte im FiFo
	int_IstAnzahlMittelwerteFiFo = str_EinSpeicherwert.ToFloat();								!Anzahl Werte im FiFo
	real_GleitenderMittelwert = real_Messwert;	!den aktuellen Messwert uebernehmen, dann den FiFo abklappern
	int_index = 1;								!erster Messwert wurde ja schon eingelesen
	str_FiFoNeu = real_Messwert.ToString();		!den neuen Messwert in den FiFo an den Anfang setzen
	
	int_DifAnzahlZusatzWerte = int_SollAnzahlMittelwerte - int_IstAnzahlMittelwerteFiFo;		!feststellen ob der FiFo groesser, kleiner oder gleich gross bleiben soll
	if (int_DifAnzahlZusatzWerte>=1)
	{
		while (int_DifAnzahlZusatzWerte>0)
		{
			str_FiFoNeu = str_FiFoNeu#TrennzeichenWerte#real_Messwert.ToString();
			real_GleitenderMittelwert = real_GleitenderMittelwert + real_Messwert.ToString();
			int_index = int_index +1;
			int_DifAnzahlZusatzWerte = int_DifAnzahlZusatzWerte -1;
		}
	}
	foreach(str_EinSpeicherwert, str_FiFoKomplett.Split(TrennzeichenWerte))
	{
		if (int_index < int_SollAnzahlMittelwerte)
		{
			str_FiFoNeu = str_FiFoNeu#TrennzeichenWerte;
			str_FiFoNeu = str_FiFoNeu#str_EinSpeicherwert;
			real_GleitenderMittelwert = real_GleitenderMittelwert + str_EinSpeicherwert.ToFloat();		!den naechsten Messwert aus dem FiFo mit berechnen
			int_index = int_index +1;
		}
		!weitere Werte werden ignoriert weil FiFo Soll Anzahl erreicht wurde
	}

	!Index 0 der Listvariable fertig stellen - FiFo
	str_FiFoKomplett = str_FiFoNeu#TrennzeichenDerZeilen;
	
	!Index 1 der Listvariable fertig stellen - Quell Geraet oder Quell Variable
	if (str_NameMesswertGeraet!="")
	{
		str_FiFoKomplett = str_FiFoKomplett#str_NameMesswertGeraet#TrennzeichenDerZeilen;
	}
	else
	{
		str_FiFoKomplett = str_FiFoKomplett#str_NameMesswertSystemvariable#TrennzeichenDerZeilen;
	}

	!Index 2 der Listvariable fertig stellen - Name der Systemvariable fuer die Ablage gleitender Mittelwert
	real_GleitenderMittelwert = real_GleitenderMittelwert / int_index;		!Berechnung neuer gleitender Mittelwert
	str_EinSpeicherwert = svObjekt.ValueList().StrValueByIndex(TrennzeichenDerZeilen, 2);
	str_FiFoKomplett = str_FiFoKomplett#str_EinSpeicherwert#TrennzeichenDerZeilen;
	dom.GetObject(str_EinSpeicherwert).State(real_GleitenderMittelwert);		!aktuellen berechneten gleitenden Mittelwert in die Systemvariable schreiben

	!Index 3 der Listvariable fertig stellen - Anzahl der gleitenden Mittelwerte im FiFo
	str_FiFoKomplett = str_FiFoKomplett#int_index;
	svObjekt.State(0);
	svObjekt.ValueList(str_FiFoKomplett);	!Variableninhalt schreiben
}
else
{
	!Die Systemvariable enthaelt Bloedsinn weil sie gerade angelegt wurde
	!Index 0 zusammenbauen
	int_index=0;
	str_WertelisteKomplett = "";
	str_WertelisteKomplett = str_WertelisteKomplett#real_Messwert.ToString();
	int_index = int_index + 1;
	while (int_index<int_SollAnzahlMittelwerte)
	{
		str_WertelisteKomplett = str_WertelisteKomplett#TrennzeichenWerte;
		str_WertelisteKomplett = str_WertelisteKomplett#real_Messwert.ToString();
		int_index = int_index + 1;
	}
	str_WertelisteKomplett = str_WertelisteKomplett#TrennzeichenDerZeilen;
	!Index 1 zusammenbauen
	str_WertelisteKomplett = str_WertelisteKomplett#str_NameMesswertGeraet#TrennzeichenDerZeilen;
	!Index 2 zusammenbauen
	str_WertelisteKomplett = str_WertelisteKomplett#svMittelwertGleitend#TrennzeichenDerZeilen;
	!Index 3 zusammenbauen
	str_WertelisteKomplett = str_WertelisteKomplett#int_index;
	dom.GetObject(dom.GetObject(svNameWerteliste)).ValueList(str_WertelisteKomplett);		!wieder abspeichern der korrigierten Systemvariable
	
	!in die Systemvariable den Messwert als gleitenden Mittelwert schreiben
real_GleitenderMittelwert = real_Messwert;
WriteLine("Messwert:" # real_Messwert);
WriteLine("Type 3=real; 4=string: " # real_Messwert.VarType());    
}
wenn ich das so teste, dann gibts keine Ausgabe von den Writelines

MichaelN
Beiträge: 9679
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 700 Mal
Danksagung erhalten: 1626 Mal

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von MichaelN » 20.05.2023, 17:59

Ok... Man sollte sich den ganzen Code ansehen.
Das ist Teil eines If-Else-Blocks, der mit diesem Kommentar eingeleitet wird

Code: Alles auswählen

!Die Systemvariable enthaelt Bloedsinn weil sie gerade angelegt wurde
Das macht aber IMHO wenig Sinn, da sonst nirgends Daten in der durch svMittelwertGleitend spezifizierten SV abgelegt werden.

Also ich bin da raus. Nimm mein Skript, das funktioniert und da kann ich auch Sonderlocken supporten.
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 +++

[sprotte80]
Beiträge: 336
Registriert: 05.10.2020, 18:37
System: CCU
Hat sich bedankt: 30 Mal
Danksagung erhalten: 25 Mal

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von [sprotte80] » 20.05.2023, 19:48

Hi
MichaelN hat geschrieben:
20.05.2023, 17:59
Ok... Man sollte sich den ganzen Code ansehen.
Das ist Teil eines If-Else-Blocks, der mit diesem Kommentar eingeleitet wird

Code: Alles auswählen

!Die Systemvariable enthaelt Bloedsinn weil sie gerade angelegt wurde
Das macht aber IMHO wenig Sinn, da sonst nirgends Daten in der durch svMittelwertGleitend spezifizierten SV abgelegt werden.
Macht schon Sinn wenn man den Code verstehen tut.
Und is ja nicht der einzige Teil wo in die SV geschrieben wird.
Der else-Part wird nur durchlaufen wenn die SysVar neu angelegt wurde. Da stehen noch keine richtigen Datas drin und daher auch der kommentar zum Block.
Da bein TE ja schon Datas gespeichert sind kommt es nicht in den else-Part sondern in den if-part. Auch im if-Part wird der Mittelwert in die SV gespeichert. Die Writelines müssen in den if-Part und nich in den else-Part.

Thomas
Wenn du keine App zur Bedienung brauchst, dann hast du kein Smarthome, sondern nur eine angefangene Baustelle, oder nur ein unsmartes Autohome.

Homematic-Script - ScriptLexikon für alle
Methoden Konstanten
Hilfe und Infos erwünscht. Alle können mitmachen. Keine Levels. Keine Geheimtuerei.

MichaelN
Beiträge: 9679
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 700 Mal
Danksagung erhalten: 1626 Mal

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von MichaelN » 20.05.2023, 20:04

Keine Lust fremden Code zu analysieren. Kannst du ruhig übernehmen.
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 +++

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

Re: Script zur Ermittlung eines gleitenden Mittelwertes

Beitrag von Henke » 20.05.2023, 20:05

Meinen liest du gerne... 8)

Antworten

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