Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

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

Moderator: Co-Administratoren

Stefan0815
Beiträge: 186
Registriert: 16.04.2019, 15:15
Hat sich bedankt: 13 Mal
Danksagung erhalten: 12 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von Stefan0815 » 20.01.2025, 21:28

...muss ich nachsehen. Dauert eventuell ein paar Tage.
Viele Grüße
Stefan

Stefan0815
Beiträge: 186
Registriert: 16.04.2019, 15:15
Hat sich bedankt: 13 Mal
Danksagung erhalten: 12 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von Stefan0815 » 21.01.2025, 13:30

Beim ersten "Sammel"-ScriptTeil ist es ja recht einfach. Man legt einfach eine Stringvariable als LogSpeicher an, die den entsprechenden Namen im Script hat.

string LogVariable = "UmweltWindLog";

Dies macht man dann einfach für jeden Messwert, den man auswerten möchte. Verändert werden dabei im jeweiliegn Script nur die 3-4 Zeilen. Das ist einfach ein universeller Datenspeicher für einen bestimmten Zeitabschnitt (in Sekunden). Diesen Scriptteil kann man auch einzeln verwenden. Ergebnis:
Screenshot 2025-01-21 132326.png
Der zweite Teil nutzt die "newlist" des ersten Teils, muss also für die Auswertung direkt anschließen. Alle Variablen die im Script als "string *Variable" definiert werden (Beispiel: string GMWLogVariable), müssen als Zahl vorher angelegt werden. Nach grober Durchsicht dürften das 4 Variablen sein, die angelegt werden. Mittelwert und Standardabweichung werden ja nur intern benutzt und nicht gespeichert.
Screenshot 2025-01-21 132325.png
Screenshot 2025-01-21 132325.png (17.23 KiB) 376 mal betrachtet
Viele Grüße
Stefan

Benutzeravatar
joni-blue
Beiträge: 1201
Registriert: 04.01.2012, 12:20
System: CCU
Wohnort: Hannover
Hat sich bedankt: 7 Mal
Danksagung erhalten: 1 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von joni-blue » 21.01.2025, 14:31

hi, beide script hintereinander im Programm code einfügen oder werden diese separat ausgelöst?
Reboot tut gut ! ! !

Stefan0815
Beiträge: 186
Registriert: 16.04.2019, 15:15
Hat sich bedankt: 13 Mal
Danksagung erhalten: 12 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von Stefan0815 » 21.01.2025, 14:33

Entweder nur Teil1 oder aber beide hintereinander. Teil2 benutzt eine Variable aus Teil1.
Viele Grüße
Stefan

Benutzeravatar
joni-blue
Beiträge: 1201
Registriert: 04.01.2012, 12:20
System: CCU
Wohnort: Hannover
Hat sich bedankt: 7 Mal
Danksagung erhalten: 1 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von joni-blue » 21.01.2025, 14:36

danke dann probiere ich später mal
Reboot tut gut ! ! !

Benutzeravatar
joni-blue
Beiträge: 1201
Registriert: 04.01.2012, 12:20
System: CCU
Wohnort: Hannover
Hat sich bedankt: 7 Mal
Danksagung erhalten: 1 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von joni-blue » 21.01.2025, 20:53

Hi, ist das so richtig?

Zusammenfassung
Du solltest folgende Variablen anlegen:

Variable Typ Beschreibung
UmweltWindLog Zeichenkette Speichert Winddaten mit Zeitstempeln.
GMWWindLong Zahl Gewichteter Mittelwert (long).
GMWWindShort Zahl Gewichteter Mittelwert (short).
WindLong95 Zahl 95%-Grenzwert (long).
WindShort95 Zahl 95%-Grenzwert (short).
Wind Logisch Zustand der Markisensteuerung (true = eingefahren).

Stefan0815 hat geschrieben:
21.01.2025, 13:30
Beim ersten "Sammel"-ScriptTeil ist es ja recht einfach. Man legt einfach eine Stringvariable als LogSpeicher an, die den entsprechenden Namen im Script hat.

string LogVariable = "UmweltWindLog";

Dies macht man dann einfach für jeden Messwert, den man auswerten möchte. Verändert werden dabei im jeweiliegn Script nur die 3-4 Zeilen. Das ist einfach ein universeller Datenspeicher für einen bestimmten Zeitabschnitt (in Sekunden). Diesen Scriptteil kann man auch einzeln verwenden. Ergebnis:

Screenshot 2025-01-21 132326.png

Der zweite Teil nutzt die "newlist" des ersten Teils, muss also für die Auswertung direkt anschließen. Alle Variablen die im Script als "string *Variable" definiert werden (Beispiel: string GMWLogVariable), müssen als Zahl vorher angelegt werden. Nach grober Durchsicht dürften das 4 Variablen sein, die angelegt werden. Mittelwert und Standardabweichung werden ja nur intern benutzt und nicht gespeichert.

Screenshot 2025-01-21 132325.png
Reboot tut gut ! ! !

Stefan0815
Beiträge: 186
Registriert: 16.04.2019, 15:15
Hat sich bedankt: 13 Mal
Danksagung erhalten: 12 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von Stefan0815 » 22.01.2025, 14:50

...hier mal meine kompletten Programme und Scripte:

Code: Alles auswählen

!- liefert Wind-Werte der letzten 6h, 05.05.2020

string DeviceChannelName = "Wetterstation:1";
string LogVariable = "UmweltWindLog";
string LogValue = "WIND_SPEED";
integer SecondsLog = 21600;
real Faktor = 2.0;

!- aktuelle Uhrzeit über Datum und 24-Stunden Zeit als Integer in Sekunden
integer now = system.Date("%F %X").ToTime().ToInteger();
!- aktuelle LogVariable auslesen
string list = dom.GetObject(LogVariable).Value();
string index;
integer count = 1; !- da es bei Eventauslösung immer ein (neues) Element gibt
!- neues Element an den Anfang der neuen Liste stellen
string newlist = dom.GetObject(DeviceChannelName).DPByHssDP(LogValue).Timestamp().ToTime().ToInteger().ToString()+"#"+dom.GetObject(DeviceChannelName).DPByHssDP(LogValue).Value().Round(1).ToString().RTrim("0").RTrim(".");

!- durch alle Listenelemente, um bereits gespeicherte Elemente, die noch nicht zu alt sind, in die neue Liste aufzunehmen, Liste wird HINTEN um zu alte Elemente abgeschnitten
foreach (index, list){
  !- Zeitauswertung für alle ALTEN Listenelemente
  if ((now-index.StrValueByIndex("#", 0).ToInteger())<=SecondsLog){
    newlist=newlist+"\t"+index;
    count=count+1;
  }
}

dom.GetObject(LogVariable).State(newlist); !- neue LOG-Liste schreiben
!- WriteLine(newlist.Replace("\t","@"));

!------------------- Mittelwert, gewichteter Mittelwert, Varianz und Standardabweichung für Long --------------------

string GMWLogVariable = "GMWWindLong"; !- Variable für gewichteten Mittelwert
string WindLong95Variable = "WindLong95"; !- Variable für WindLong95
integer GMWSecondsLog = 5400; !- Zeitspanne für gewichteten Mittelwert in Sekunden: 5400 (90 Minuten)
real sumMW;

!- Anzahl Elemente für Zeiteinheit ermitteln und "normalen" Mittelwert berechnen
integer count = 0;
foreach (index, newlist){
  if ((now-index.StrValueByIndex("#", 0).ToInteger())<=GMWSecondsLog){
    sumMW = sumMW + index.StrValueByIndex("#", 1).ToFloat();
    count=count+1;
  }
}
real MWLong = sumMW/count; !- Mittelwert für Long

real sumVQ;
foreach (index, newlist){
  if ((now-index.StrValueByIndex("#", 0).ToInteger())<=GMWSecondsLog){
    sumVQ = sumVQ + ((index.StrValueByIndex("#", 1).ToFloat() - MWLong) * (index.StrValueByIndex("#", 1).ToFloat() - MWLong));
  }
}

real VarianzLong = sumVQ/count;
real StandAbwLong = VarianzLong.Sqrt();
real WindLong95 =  MWLong+(StandAbwLong*Faktor);
dom.GetObject(WindLong95Variable).State(WindLong95.Round(2)); !- WindLong95 schreiben

real countGMW = ((count*(count+1))/2);
real sumGMW;
integer c = 0; !- Zähler für Gewichtung
foreach (index, newlist){
  if ((now-index.StrValueByIndex("#", 0).ToInteger())<=GMWSecondsLog){
    sumGMW=sumGMW+(index.StrValueByIndex("#", 1).ToFloat()*(count-c));
    c=c+1;
  }
}

real GMW = sumGMW/countGMW;
dom.GetObject(GMWLogVariable).State(GMW.Round(2)); !- neuen gewichteten Mittelwert für Long schreiben
!- WriteLine(GMW.Round(2));

!------------------- Mittelwert, gewichteter Mittelwert, Varianz und Standardabweichung für Short --------------------

string GMWLogVariable = "GMWWindShort"; !- Variable für gewichteten Mittelwert
string WindShort95Variable = "WindShort95"; !- Variable für WindLong95
integer GMWSecondsLog = 1800; !- Zeitspanne für gewichteten Mittelwert in Sekunden: 1800 (30 Minuten)
real sumMW;

!- Anzahl Elemente für Zeiteinheit ermitteln und "normalen" Mittelwert berechnen
integer count = 0;
foreach (index, newlist){
  if ((now-index.StrValueByIndex("#", 0).ToInteger())<=GMWSecondsLog){
    sumMW = sumMW + index.StrValueByIndex("#", 1).ToFloat();
    count=count+1;
  }
}
real MWShort = sumMW/count; !- Mittelwert für Short

real sumVQ;
foreach (index, newlist){
  if ((now-index.StrValueByIndex("#", 0).ToInteger())<=GMWSecondsLog){
    sumVQ = sumVQ + ((index.StrValueByIndex("#", 1).ToFloat() - MWShort) * (index.StrValueByIndex("#", 1).ToFloat() - MWShort));
  }
}
real VarianzShort = sumVQ/count;
real StandAbwShort = VarianzShort.Sqrt();
real WindShort95 =  MWShort+(StandAbwShort*Faktor);
dom.GetObject(WindShort95Variable).State(WindShort95.Round(2)); !- WindShort95 schreiben

real countGMW = ((count*(count+1))/2);
real sumGMW;
integer c = 0; !- Zähler für Gewichtung
foreach (index, newlist){
  if ((now-index.StrValueByIndex("#", 0).ToInteger())<=GMWSecondsLog){
    sumGMW=sumGMW+(index.StrValueByIndex("#", 1).ToFloat()*(count-c));
    c=c+1;
  }
}

real GMW = sumGMW/countGMW;
dom.GetObject(GMWLogVariable).State(GMW.Round(2)); !- neuen gewichteten Mittelwert für Short schreiben
!- WriteLine(GMW.Round(2));
Script 1 macht die Datenanalyse und Speicherung
Screenshot 2025-01-22 143031.jpg
Script 2 setzt dann logische Variablen auf der Basis der Werte:

Code: Alles auswählen

!- Schwellenwerte für "Wind" und "leichten Wind"
string DeviceChannelName = "Wetterstation:1";
string LogValue = "WIND_SPEED";
real WindSpeed = dom.GetObject(DeviceChannelName).DPByHssDP(LogValue).Value();
string LogValue = "WIND_THRESHOLD_OVERRUN";
boolean WindThreshold = dom.GetObject(DeviceChannelName).DPByHssDP(LogValue).Value();
real WindLong95 = dom.GetObject("WindLong95").Value();
real WindShort95 = dom.GetObject("WindShort95").Value();
string nowString = system.Date("%F %X");
integer now = nowString.ToTime().ToInteger();
integer StatusChangeWind = dom.GetObject("StatusChangeWind").Value().ToTime().ToInteger();
integer StatusChangeLightWind = dom.GetObject("StatusChangeLightWind").Value().ToTime().ToInteger();
integer MinChangeBackTime = 9000;
real WindOnSchwelle = 35.0;
real WindOffSchwelle = 35.0;
real LeichtWindOnSchwelle = 25.0;
real LeichtWindOffSchwelle = 25.0;

!- Bereich: Wind
if ((WindSpeed>WindOnSchwelle) || (WindThreshold)){  !- Schwelle für Wind
   dom.GetObject("Wind").State(true);
   dom.GetObject("leichter Wind").State(true);
   dom.GetObject("StatusChangeWind").State(nowString);
   dom.GetObject("StatusChangeLightWind").State(nowString);
}
else
{
   if ((WindLong95<WindOffSchwelle) && (WindShort95<WindOffSchwelle) && (WindThreshold==false) && ((now-StatusChangeWind)>MinChangeBackTime)){  !- "Wind" Schwelle zurücksetzen
       dom.GetObject("Wind").State(false);
   }
   else {
      dom.GetObject("Wind").State(dom.GetObject("Wind").Value());
   }
   !- Bereich: leichter Wind
   if ((WindSpeed>LeichtWindOnSchwelle)){ !- Schwelle für leichten Wind
      dom.GetObject("leichter Wind").State(true);
      dom.GetObject("StatusChangeLightWind").State(nowString);
   }
   else {
      if ((WindLong95<LeichtWindOffSchwelle) && (WindShort95<LeichtWindOffSchwelle) && ((now-StatusChangeLightWind)>MinChangeBackTime)){  !- "leichter Wind" Schwelle zurücksetzen
        dom.GetObject("Wind").State(false);
        dom.GetObject("leichter Wind").State(false);
      }
      else {
        dom.GetObject("leichter Wind").State(dom.GetObject("leichter Wind").Value());
      }
   }
}
Screenshot 2025-01-22 143543.jpg
Beim zweiten Script werden noch 2 String Variablen benötigt, die den Zeitstempel für die letzte Änderung halten. Ist schon 5 Jahre her.... Ich muss da erst wieder reinfinden. Läuft ansonsten bei mir mit 2 Markisen problemlos.
Viele Grüße
Stefan

Benutzeravatar
joni-blue
Beiträge: 1201
Registriert: 04.01.2012, 12:20
System: CCU
Wohnort: Hannover
Hat sich bedankt: 7 Mal
Danksagung erhalten: 1 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von joni-blue » 24.01.2025, 12:04

Kann man die Berechnung auch so umstellen das die größeren Werte stärker berechnet werden?
Reboot tut gut ! ! !

Stefan0815
Beiträge: 186
Registriert: 16.04.2019, 15:15
Hat sich bedankt: 13 Mal
Danksagung erhalten: 12 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von Stefan0815 » 24.01.2025, 13:16

Sicher, statistisch ist das aber nicht wirklich sinnhaft. Ein reverse gewichteter Mittelwert betrachtet die Daten kontinuierlich im Zeitverlauf, nicht nach Einzelevent. Bei zwei betrachteten Zeitabschnitten kann man dann sehr genau die Tendenz ablesen. Genau das möchte man bei Wind, da sich dieser ja stetig über den Tag ändert.
Viele Grüße
Stefan

Benutzeravatar
joni-blue
Beiträge: 1201
Registriert: 04.01.2012, 12:20
System: CCU
Wohnort: Hannover
Hat sich bedankt: 7 Mal
Danksagung erhalten: 1 Mal

Re: Markisensteuerung: Hysterese 2.0, gewichteter Mittelwert, Standardabweichung von Sensordaten

Beitrag von joni-blue » 25.01.2025, 18:35

Hi, was genau macht man mit der "VarianzLong" und short?
lg
Reboot tut gut ! ! !

Antworten

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