10600 Zeichen
Score aktualisiert
100%
Code: 142ac7e3653a4fabae9ba85c4370bae0
Token in Entwicklung nicht aktualisiert
img-Tag in Entwicklung deaktiviert
Lassen Sie mich ausholen.
Der Kombisensor begleitet meine ursprüngliche HomeMatic-Installation fast so lange,
wie ich sie habe. Wobei man das einschränken muss: Die ersten beiden haben
nicht mehr als zwei oder drei Jahre gehalten, der dritte zeigt jetzt nach rund sieben Jahren erste
Ausfallerscheinungen.
Die Daten schreibe ich in eine
MySQL-Datenbank auf meinen Server im Keller, der dadurch inzwischen mehrere Jahre
nutzloser, unkalibrierter Wetterdaten enthält. Na gut, halb nutzlos: Immerhin habe ich
dadurch eine Wetterstation auf meiner
Webseite und auf einem alten iPad im Schrank.
Weil ich weiterhin anhand von Wind, Temperatur und Regen die Heizung regeln und vor
allem die Fenster schließen wollte, wurde das letzte Exemplar des Kombisensors ersetzt,
und weil ich eh keine Windrichtung brauche, hat der HomeMatic-Kombisensor einem
Wettersensor Plus aus der HomeMatic-IP-Reihe Platz gemacht. Glücklicherweise kann man ja
die HomeMatic-IP-Komponenten auch an einer alten CCU2 anlernen.
So ganz kaputt ist der alte freilich noch nicht: Helligkeit, Regenmenge und Temperatur
funktionieren noch leidlich und das Gehäuse ist bei der Demontage nur zum Teil
zerbrochen. Darum habe ich ihn kurzerhand in unserer Zweitwohnung an den Balkon
geschraubt, damit er dort in der neuen
HomeMatic-Installation zum Einsatz kommen kann. Von weitem sieht man auch nicht das
halbe Pfund Heißkleber, mit dem ich die Basis zusammengeklebt habe. Hoffentlich fällt er
auf unsere Seite des Balkons, wenn er fällt, nicht auf den Nachbarbalkon.
HomeMatic-Kombisensor an seinem neuen Standort
Weil ich in der Zweitwohnung bisher keinen Server mit Datenbank herumstehen habe
(jedenfalls nicht im Dauerbetrieb), gibt es auch keine schnelle Möglichkeit, die Frage zu
beantworten, was die Minimal- und Maximaltemperaturen der letzten 24 Stunden waren und
wieviel es geregnet hat. Werte für gestern und heute wären kein Problem – da hatte ich schon mal was –, aber Werte für 24 Stunden
ohne Datenbank-Protokollierung: problematisch.
Und darum habe ich mal was geschrieben.
Neue Script-Funktionen
Mit Firmware 2.29.22 wurden neue Funktionen in der Scriptsprache der CCU
eingeführt, die auf dieser Seite genutzt werden. Achten Sie darauf, als
Logikschicht-Version in den Systemeinstellungen der CCU nicht „Legacy“ zu wählen.
Wenn Sie eine ältere Firmware verwenden oder als Logikschicht-Version „Legacy“
ausgewählt haben, werden Sie Script-Fehler angezeigt bekommen, wenn Sie diese
Anleitung umsetzen. Die Programme werden nicht funktionieren.
Aktualisieren Sie die Firmware Ihrer CCU! Wählen Sie „Standard“ als
Logikschicht-Version aus!
Variablen in HomeMatic-Scripten
Die CCU hatte früher ein Limit von maximal 200 Variablen, das mit
Firmware-Version 2.29.18 aufgehoben wurde. Dieses Limit bezog sich auf alle
Variablen, die in allen Scripten verwendet werden. Gemeint sind Variablen,
die direkt im Script definiert werden: object x; object y;
var z;
Wenn Scripte nicht mehr funktionieren und bei der Prüfung unerklärliche
Syntax-Fehler auftreten, sollte versuchsweise dieses Programm wieder gelöscht
oder deaktiviert werden – oder, noch besser, auf die aktuelle
Firmware-Version aktualisiert werden.
Strings in HomeMatic-Scripten
Durch String-Verwendung in HomeMatic-Scripten kann die CCU fehlerhaft arbeiten,
instabil werden oder sogar abstürzen. Grundsätzlich gilt: Je öfter mit Strings
hantiert wird, desto eher führt dies zu Problemen.
Ich empfehle daher, nach Umsetzung dieser Anleitung die CCU unter Beobachtung
zu halten.
String-Verlängerung
In den Scripten auf dieser Seite werden Strings verlängert
(x = x # y).
Dies führt oft zu Störungen bei der Ausführung von Programmen:
- Scripte in Programmen werden nicht mehr ausgeführt
- bei der Fehlerprüfung erscheinen unerklärliche Syntax-Fehler
Durch einen Neustart werden diese Probleme (vorübergehend) behoben. Auch hier
hängt die Dauer, bis es zu Störungen kommt, davon ab, wie häufig diese
Programmschritte ausgeführt werden.
Programmlogik
Die Idee hinter diesem Programm ist folgende: In einer Systemvariable speichere ich die
Minimum-/Maximum-Werte der letzten 24 Stunden. Jedes Mal, wenn der Kombisensor einen Wert
sendet, wird die Variable aktualisiert:
- bestehende Werte werden übernommen
- Werte für die aktuelle Stunde werden aktualisiert
- Werte für die nächste Stunde werden zurückgesetzt, damit sie wieder neu befüllt
werden können
Maximal- und Minimalwert aus der gesamten Reihe sind dann Maximal- und Minimalwert für
24 Stunden.
Der Einfachheit halber verwende ich die Stunde der aktuellen Uhrzeit als Index für die
Zeichenkette. Damit habe ich automatisch Werte für 24 Stunden – jedenfalls fast:
Strenggenommen sind es 22 bis 23 Stunden, denn eine der 24 Stunden wird immer gerade
aktualisiert und eine weitere wird immer gerade zurückgesetzt. Aber damit kann ich leben.
Systemvariable
Als erstes lege ich wie immer die benötigten Systemvariablen an.
Für die Zwischenspeicherung der Werte brauche ich eine Zeichenkette. Diese nenne ich Außentemperatur
24h.
Damit ich Minimum und Maximum beim Kombisensor anzeigen oder in Programmen verwenden
kann, gibt es noch zwei Werte, die den Temperaturbereich des Kombisensors (-30 °C bis +60
°C) abdecken.
Außentemperatur min und Außentemperatur max ordne ich dem Gerät Kombisensor
zu. Dadurch werden die Variablen dann in der WebUI direkt beim Gerät angezeigt.
Wenn ich die Variablen in Programmen verwenden will, greife ich ebenfalls über das
Gerät darauf zu – nur in Scripten gehe ich weiter über die Namen Außentemperatur
min und Außentemperatur max.
WebUI-Programm
Die eigentliche Arbeit wird ein Script erledigen, aber um ein Script auszuführen,
brauche ich natürlich ein kleines WebUI-Programm
Die Programmlogik ist einfach: Immer, wenn der Kombisensor eine gültige Temperatur
meldet, wird das Script ausgeführt. Wichtig ist, dass das Programm bei Aktualisierung
ausgelöst wird, damit entsprechend der Logik
von WebUI-Programmen bei jeder Temperaturmeldung das Script ausgeführt wird.
Die Beschränkung auf den Temperaturbereich zwischen -30 und +60 °C habe ich
eingebaut, weil mein sterbender Kombisensor gerne mal stundenlang 80 °C meldet. In diesen
Fällen lasse ich meine Minimal- und Maximaltemperaturen einfach nicht aktualisieren.
Die Verzögerung von 5 Sekunden wäre für das hier vorgestellte Programm eigentlich
nicht nötig. Ich lasse die Werte allerdings auch über die PHP-DB in eine Datenbank eintragen, und weil da
natürlich auch andere Werte des Kombisensors festgehalten werden, entzerre ich die
Aktualisierung an dieser Stelle.
Ausgeführtes Script
Das Script, das hier ausgelöst wird, ist etwas länger.
gesamtes Script markieren / kopieren
! HomeMatic-Script
! EIN TEMPERATUR-MINIMAX DER LETZTEN 24 STUNDEN
! http://www.christian-luetgens.de/homematic/programmierung/garten/tagesverlauf/24-Stunden-Wetter.htm
object o_temp = dom.GetObject ("$src$");
if (o_temp) {
r_temp = o_temp.Value();
object o_verlauf = dom.GetObject ("Außentemperatur 24h");
string s_verlauf_alt = o_verlauf.Value();
string s_verlauf_neu = "";
integer i_now = system.Date ("%H").ToInteger();
real r_temp_min = 60.0;
real r_temp_max = -30.0;
string s_delimiter = "";
integer i = 0;
real r_max;
real r_min;
string s;
while (i < 24) {
if (i == ((i_now + 1) % 24)) {
s = "60.0:-30.0";
} else {
s = s_verlauf_alt.StrValueByIndex (";", i);
r_min = s.StrValueByIndex (":", 0).ToFloat();
r_max = s.StrValueByIndex (":", 1).ToFloat();
if (i == i_now) {
r_min = r_min.Min (r_temp);
r_max = r_max.Max (r_temp);
}
s = r_min.ToString (1) # ":" # r_max.ToString (1);
r_temp_min = r_temp_min.Min (r_min);
r_temp_max = r_temp_max.Max (r_max);
}
s_verlauf_neu = s_verlauf_neu # s_delimiter # s;
s_delimiter = ";";
i = i + 1;
}
o_verlauf.State (s_verlauf_neu);
dom.GetObject ("Außentemperatur min").State (r_temp_min);
dom.GetObject ("Außentemperatur max").State (r_temp_max);
}
! Ende des Scripts
Die einzelnen Programmschritte sehen wie folgt aus:
- Als erstes wird der Datenpunkt ermittelt, in dem die Temperatur gemeldet wird. $src$
wird immer mit dem Datenpunkt gefüllt, der das Programm auslöst – in diesem Fall also
die Temperatur des Kombisensors.
- Das weitere Programm wird nur ausgeführt, wenn ein Datenpunkt gefunden wird. Bei
manueller Auslösung oder bei Auslösung durch den Neustart der CCU ist $src$
leer; so verhindere ich, dass in diesen Fällen Nullwerte festgehalten werden.
- Ich sammle meine Werte und Systemvariablen ein: r_temp als aktuelle Temperatur
des Kombisensors, s_verlauf_alt als bisheriger Wert der Systemvariablen Außentemperatur
24h. Die Stunde der aktuellen Uhrzeit wird in i_now gespeichert.
- Die Variablen für die neue 24-Stunden-Zeichenkette sowie Minimal- und Maximalwerte
werden initialisiert.
- Als nächstes kommen einige Variablen für die while-Schleife, in der die
eigentliche Arbeit stattfindet, indem für jede Stunde des Tages s_verlauf_neu
ausgefüllt wird.
- In der while-Schleife iteriert das Script durch die Stunden des Tages: Für die
nächste Stunde nach i_now werden Minimum und Maximum zurückgesetzt, um nach dem
nächsten Stundenwechsel aktualisiert werden zu können. Anderenfalls werden Minimum und
Maximum in r_min und r_max ausgelesen und für die aktuelle Stunde
aktualisiert. Außerdem werden die Variablen r_temp_min und r_temp_max
mit dem 24-Stunden-Minimum und -Maximum befüllt. Am Ende wird die neue Zeichenkette
stundenweise ergänzt.
- Nachdem die 24 Stunden eines Tages abgearbeitet wurden, wird der neue Tagesverlauf
abgespeichert. Außerdem werden Außentemperatur min und Außentemperatur max
mit den Werten befüllt, die für die vergangenen 24 Stunden errechnet wurden.
In der Systemvariablen Außentemperatur 24h kann man nach den ersten 24
Stunden verfolgen, wie die Werte protokolliert werden.
Für jede Stunde gibt es einen Minimal- und einen Maximalwert, getrennt durch einen
Doppelpunkt. Die Werte der einzelnen Stunden sind durch Semikolons getrennt. Auf diese
Weise kann ich mittels StrValueByIndex() darauf zugreifen und ein bisschen so
tun, als sei mein String ein Array.
Wer ganz genau hinsieht, erkennt an dieser Stelle auch, warum meine Minimum- und
Maximum-Werte eigentlich keine 24 Stunden abbilden, sondern nur 22 bis 23. Irgendwo in der
Mitte werden die Werte auf 60.0:-30.0 gesetzt – das ist die Initialisierung für
die Folgestunde. Das Doppel 13.1:13.2 davor ist Minimum und Maximum der aktuellen
Stunde.
Sehr viel besser sehen natürlich die Minimum- und Maximum-Werte in der WebUI beim
Kombisensor aus:
Ich habe auf dem Screenshot einige Datenpunkte ausgeblendet, damit die beiden
Systemvariablen in der letzten Zeile voll zur Geltung kommen.
Optionen
Außentemperatur speichern
Da ich weitere Fehlfunktionen meines Kombisensors erwarte und dessen Werte darum besser
nicht direkt in Programmen verwenden möchte, habe ich eine Systemvariable Außentemperatur
erstellt, die ich ebenfalls bei Aktualisierung befülle und die ich in anderen Programmen
ansprechen kann.
Das mache ich durch eine einzelne zusätzliche Zeile, die am Anfang des Scripts
eingefügt wird:
[...]
if (o_temp) {
r_temp = o_temp.Value();
dom.GetObject ("Außentemperatur").State (r_temp);
[...]
Gleichzeitig wird es damit sehr viel einfacher, wenn ich den Kombisensor irgendwann
gegen einen anderen Sensor austauschen muss oder die Temperatur anders berechne: Ich muss
nicht alle Programme anfassen, die die Temperatur verwenden, sondern nur dieses.
Wie schon bei der Vorstellung des WebUI-Programms angekündigt, lasse ich die
Temperatur auch in eine Datenbank bei bplaced eintragen. Das erledigen zwei Zeilen am Ende
des Scripts sowie mein Mini-Framework.
[...]
o_verlauf.State (s_verlauf_neu);
dom.GetObject ("Außentemperatur min").State (r_temp_min);
dom.GetObject ("Außentemperatur max").State (r_temp_max);
dom.GetObject ("PHP-DB Table").State ("Temperatur");
dom.GetObject ("PHP-DB Value").State (r_temp);
}
Nach einigen Tagen der Datensammlung habe ich schon eine ansehnliche Statistik.
utc_time |
min_val |
avg_val |
max_val |
2021-04-25 |
6.90 |
11.51 |
17.40 |
2021-04-26 |
0.00 |
8.94 |
14.80 |
2021-04-27 |
3.80 |
10.56 |
18.00 |
2021-04-28 |
5.40 |
13.02 |
19.80 |
2021-04-29 |
11.80 |
15.56 |
23.40 |
2021-04-30 |
12.10 |
17.27 |
24.20 |
2021-05-01 |
13.00 |
19.62 |
26.00 |
2021-05-02 |
13.10 |
16.21 |
20.20 |
Gut zu erkennen, dass ich am 26.04. irgendwas am System gefummelt habe und darum eine
störende Null in der Datenbank gelandet ist. Danach habe ich dann das Script geändert,
so dass es mit $src$ arbeitet, um solche Nulleinträge zu verhindern.
Ebenfalls gut zu erkennen, dass keine 80-Grad-Werte eingetragen wurden. Entweder der
Kombisensor funktioniert – oder meine Workarounds.