Meine WinMatic-Antriebe sind nun schon seit einigen Jahren im Einsatz. Den ersten hatte
ich als Spielerei gekauft, um ihn mal auszuprobieren – und kurz danach dann viel Geld
ausgegeben, um bis auf die Terrassentür alle Fenster damit auszustatten. Herrlich
überflüssig, aber ein toller Spaß für erwachsene Spielkinder (sog.
„Männer“).
Die Stromversorgung erfolgt über austauschbare Akku-Packs mit der schönen
Typbezeichnung HM-Sec-Win-BaP, die direkt unten am Antrieb
montiert werden. Sie können jederzeit geladen werden, auch ohne am Antrieb montiert zu
sein, und wenn sie montiert sind und das Ladegerät angeschlossen wird, dann läuft die
WinMatic auch mit Netzspannung. Wenn nur das hässliche Kabel nicht wäre.
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.
Akkus sind Verbrauchsmaterial
In den Akku-Packs befinden sich NiMh-Zellen, und die haben die unangenehme Eigenschaft,
zu altern. Irgendwann muss der Akku öfter geladen werden, die „Batterie
leer“-Warnung kommt früher, der Akku-Pack hat nicht mehr genug Kraft für den
Drehantrieb … kurz: Irgendwann ist Schluss. Akkus sind halt Verbrauchsmaterial.
Das Problem ist, dass ich meine Akku-Packs munter im ganzen Haus herumtausche. Alle
Fenster haben unterschiedliche Bewegungsprofile – manche gehen jeden Tag mehrmals auf und
zu, andere bleiben über Tage geschlossen. Durch den regelmäßigen Austausch sind sehr
wahrscheinlich alle Akku-Packs gleichmäßig belastet worden und sollten auch alle
gleichzeitig kaputt sein. Sollten sie – aber sind sie es auch?
Wie kann ich herausfinden, welcher Akku-Pack tatsächlich kaputt ist und welcher noch
nicht?
WinMatic-Bordcomputer
Wer schon mal eine Instrumententafel vor sich gesehen hat, dem wird das Konzept des
Kilometerzählers nicht völlig unbekannt sein: eine Anzeige, die für jeden
zurückgelegten Kilometer fleißig hochzählt.
Das bastele ich mir auch für die WinMatic: Bei vollem Akku wird der Zähler auf 0
zurückgesetzt und dann jedes Mal erhöht, wenn das Fenster bewegt wird. Dabei
berücksichtige ich auch unvollständige Bewegungen – von 0% bis 100% wird mehr Strecke
addiert, als wenn die WinMatic nur von 50% auf 70% bewegt wird. Auch den
Verriegelungsvorgang rechne ich mit hinzu.
Wenn der Akku-Pack dann irgendwann leer ist, kann ich auf den Zählerstand gucken und
weiß, ob er im Vergleich zu den anderen noch brauchbar ist oder nicht.
Der „Bordcomputer“ berechnet mir zwischendurch aus dem aktuellen Ladezustand
die voraussichtliche Reichweite sowie das absehbare Austauschdatum – praktisch vor dem
Urlaub. Ich sag ja immer, niemand braucht mehr als den Dreisatz im Leben.
Systemvariablen und Gewerke
Wie immer, wenn ich irgendwas irgendwo speichern oder anzeigen lassen möchte, brauche
ich Systemvariablen. In diesem Fall gibt es für jeden Akku-Pack, den ich überwachen
möchte, eine eigene Systemvariable vom Typ Zeichenkette. Diese Variablen
wiederum sind dem jeweiligen Akku-Pack als Kanal zugeordnet.
Bei meinen acht Fenstern muss ich also acht Systemvariablen erstellen.
Der zweite wichtige Punkt ist, dass ich alle Akku-Packs in einem eigenen Gewerk
zusammenfasse. Es können durchaus auch andere Kanäle mit im Gewerk sein, aber für die
Ausführungsgeschwindigkeit des Scriptes wird es am Ende am besten sein, wenn möglichst
wenige Kanäle abgearbeitet werden müssen.
Mein Gewerk heißt Energiemanagement. So heißt es schon seit vielen Jahren,
weil ich den Namen damals toll fand und ihn seitdem nicht geändert habe. Man muss auch zu
seinen Peinlichkeiten stehen.
Hier sind außer den Akku-Packs nur noch die Sensoren für meine selbstgebastelte
Energiemessung enthalten sowie der Aktor
für das WinMatic-Ladegerät in meinem Treppenhaus.
WebUI-Programm und Script
Das Script, in dem die eigentliche Intelligenz des Programms steckt, lasse ich von
meinem Systemtakt auslösen.
Im Prinzip wäre es natürlich besser, wenn das Script stets genau dann laufen würde,
wenn irgendetwas passiert ist – das Fenster bewegt wurde oder der Ladezustand des Akkus
sich geändert hat. Allerdings müsste ich dann aufgrund der Logik von WebUI-Programmen jede
Bedingung für jedes Fenster doppelt einbauen – macht sechs Bedingungen pro Fenster. Da
ist der Systemtakt doch deutlich übersichtlicher.
Nachteil ist natürlich, dass das Script es nicht mitbekommt, wenn das Fenster zu
schnell bewegt wird. Wenn der Systemtakt nur alle zweieinhalb Minuten läuft und das
Fenster zwischen zwei Auslösungen von 30% auf 60% und gleich wieder zurück auf 30%
bewegt wurde, dann wird im Script keine Bewegung erkannt.
Im Normalfall kommt das bei mir nicht vor, deshalb spielt es für mich in der Praxis
keine große Rolle. Dazu kommt noch, dass mein Kilometerzähler natürlich kein
hochpräzises Messinstrument wird, sondern eher der groben Abschätzung der Akkureichweite
dient. Da kommt es auf vereinzelte nicht erfasste Fensterbewegungen nicht an.
Den Duty Cycle brauche ich hier
nicht zu verwenden: Das Script löst keine Aktionen aus, die zu irgendwelchen
Funk-Aktivitäten führen würden. Es kann also uneingeschränkt immer laufen.
Das Script wird mit 12 Sekunden Verzögerung ausgeführt. Man sieht es ihm nicht an,
aber es erzeugt tatsächlich etwas Last auf der CCU – und außerdem entzerre ich eh
alles, was am Systemtakt hängt.
gesamtes Script markieren / kopieren
! HomeMatic-Script
! REICHWEITEN-RECHNER FüR DIE WINMATIC
! http://www.christian-luetgens.de/homematic/programmierung/klima/reichweite/Reichweite.htm
! Objekte
object o_winmatic;
object o_akku;
object o_antrieb;
! Werte
object o_akku_reichweite;
integer i_akku_level;
integer i_antrieb_level;
integer i_strecke;
time t_timestamp;
! Ergebnis
integer i_reichweite;
time t_zeit;
string s_status;
! Hilfsvariablen
string s;
integer i;
! Konstanten
string tab = "\t";
time now = system.Date ("%F %T").ToTime();
foreach (s, dom.GetObject ("Energiemanagement").EnumUsedIDs()) {
o_akku = dom.GetObject (s);
o_winmatic = dom.GetObject (o_akku.Device());
o_akku_reichweite = dom.GetObject (o_akku.DPs().GetAt (2));
if ((o_akku.HssType() == "AKKU") && (o_winmatic.HssType() == "HM-Sec-Win") && (o_akku_reichweite)) {
s_status = o_akku_reichweite.Value().Replace ("<br />", tab).Replace (": ", tab);
t_timestamp = s_status.StrValueByIndex (tab, 3).ToTime();
i_antrieb_level = s_status.StrValueByIndex (tab, 5).ToInteger();
i_strecke = s_status.StrValueByIndex (tab, 7).ToInteger();
i_akku_level = (o_akku.DPByHssDP ("LEVEL").Value() * 100).Round().ToInteger();
if ((i_akku_level == 100) || (t_timestamp.ToInteger() <= 0)) {
t_timestamp = now;
i_strecke = 0;
i_reichweite = 0;
t_zeit = now;
} else {
o_antrieb = o_winmatic.Channels().GetAt (1);
i = o_antrieb.DPByHssDP ("LEVEL").Value();
if (i < 0) {
i = -100;
} else {
i = (i * 100).Round().ToInteger();
}
if (i <> i_antrieb_level) {
i_strecke = i_strecke + (i_antrieb_level - i).Abs().ToInteger();
i_antrieb_level = i;
}
i_reichweite = (((1.0 * i_strecke) / (100 - i_akku_level)) * 100).Round().ToInteger();
t_zeit = ((((1.0 * (now.ToInteger() - t_timestamp.ToInteger())) / (100 - i_akku_level)) * 100) + t_timestamp.ToInteger()).ToInteger().ToTime();
}
s_status = "<span style=\"color:black;\"><br /><br />" #
"Volladung<br />" # t_timestamp # "<br />" #
"Fenster: " # i_antrieb_level # "<br />" #
"Strecke: " # i_strecke # "<br />" #
"Reichweite: " # i_reichweite # "<br />" #
"Akkuwechsel: " # t_zeit.Format ("%F") #
"</span>";
o_akku_reichweite.State (s_status);
}
}
! Ende des Scripts
Und so funktioniert das Script:
Zunächst führe ich meine Variablen ein, mit denen ich im Script arbeiten werde. Ohne
Variablendeklaration gibt es Scriptfehler, gerade so, als sei die Scriptsprache der CCU
eine richtige Programmiersprache.
Ganz am Ende definiere ich noch zwei Konstanten: ein Tabulator, um irgendwelche Bugs
der CCU zu umgehen, und die Zeit aus Bequemlichkeit.
Das eigentliche Programm ist eine einzige große Schleife: Mein Gewerk Energiemanagement
wird gesucht und alle Kanäle der Reihe nach abgearbeitet. o_akku enthält den
Kanal (vielleicht ein Akku-Pack), o_winmatic enthält das Gerät, zu dem der
Kanal gehört, und o_akku_reichweite die Systemvariable, die dem Akku-Pack
zugeordnet ist.
Nur wenn o_akku tatsächlich ein AKKU ist, o_winmatic eine HM-Sec-Win
und o_akku_reichweite existiert, geht es weiter.
Status-Systemvariable laden
Der Inhalt der Systemvariablen, die dem Akku-Pack zugeordnet ist, wird zunächst in s_status
gespeichert. Dabei werden einige Formatierungen, die zur Anzeige benötigt werden, durch
Tabulatoren ersetzt.
Danach werden die bisherigen Werte ausgelesen: t_timestamp gibt den Zeitpunkt
der letzten Vollladung an, i_antrieb_level den Öffnungswinkel beim letzten
Durchlauf des Scriptes und i_strecke schließlich ist der eigentliche
Kilometerzähler.
In i_akku_level wird der aktuelle Ladezustand des Akkus gespeichert. Liegt er
bei 100% oder enthält t_timestamp keinen sinnvollen Wert, wird der Zähler
zurückgesetzt: Bei vollem Akku beginnt die Streckenmessung von vorne und wenn t_timestamp
keinen Timestamp enthält, dann machen alle weiteren Berechnungen keinen Sinn.
Beim Zurücksetzen wird natürlich i_strecke zurückgesetzt, also der
Kilometerzähler, außerdem t_timestamp, also der Zeitpunkt der letzten
Aufladung. Was i_reichweite und t_zeit bedeuten, steht im übernächsten
Absatz – aber auf jeden Fall werden auch sie hier zurückgesetzt.
Wenn die Akkuladung kleiner als 100% ist, dann befindet sich die WinMatic sehr
wahrscheinlich im Akkubetrieb und saugt ihren Energiespeicher langsam leer. Damit kann man
rechnen.
Zunächst suche ich mir den eigentlichen WinMatic-Antrieb heraus und speichere ihn in o_antrieb.
Von diesem Kanal wiederum nehme ich den Datenpunkt LEVEL, der den Öffnungswinkel
und Verriegelungszustand angibt: -0.05 bedeutet verriegelt, 0.0 bis 1.0
entspricht 0% bis 100% Öffnungswinkel.
Meine Strecke berechnet sich wie folgt: Für jeden Prozentpunkt wird ein
„Kilometer“ zu i_strecke addiert. Außerdem rechne ich den
Verriegelungsvorgang wie 100 „Kilometer“. Ich rechne den Wert also so um, dass
ich Werte von -100 (Fenster verriegelt) bis 100 (Fenster offen) erhalte:
Von Verriegelung bis zur kompletten Öffnung sind es 200 „Kilometer“.
Den Wert vergleiche ich mit dem, der in der Systemvariablen gespeichert war. Weicht er
ab, hat sich das Fenster bewegt; ich rechne die zurückgelegte Strecke aus und erhöhe i_strecke.
Nachdem ich alle Daten habe, kann ich die Werte für meinen Bordcomputer berechnen.
Dreisatz.
i_reichweite gibt die voraussichtliche Gesamtreichweite des Akku-Packs an.
Mein Ziel ist es ja, die Gesundheit meiner Akkus zu überwachen – mit dieser Prognose
bekomme ich schon mal einen ersten Hinweis.
t_zeit enthält den Zeitpunkt, zu dem der Akku voraussichtlich bei 0% sein
wird – sofern der Akku intakt ist. Wenn er halbwegs linear und gleichmäßig entleert
wird, habe ich einen Anhaltspunkt, wann ich wieder ran muss.
Die beiden Werte ist nur grobe Anhaltspunkte. Defekte Akkus neigen dazu, unvermittelt
von einem beliebigen Wert auf 0 zu springen – da fällt die Prognose der Reichweite
schwer. Außerdem hängt die Entladung natürlich davon ab, wie oft das Fenster bewegt
wird. Wenn ich einen Monat lang gar nichts mache und dann stündlich das Fenster öffne
und schließe, dann gibt es natürlich keine sinnvolle Prognose für den Wechselzeitpunkt.
Status-Systemvariable speichern
Ganz zum Schluss nehme ich all meine neuen und geänderten Werte und schreibe sie
zurück in die Systemvariable. Ich verwende dabei HTML-Formatierungen und schiebe noch ein
paar Leerzeilen ein, um mich – man ahnt es bereits – um bekannte Bugs der CCU
herumzufummeln.
Das Ergebnis kann sich sehen lassen:
Man sieht, dass der Akku-Pack meines Badfensters zuletzt am 25.09.2017 voll aufgeladen
wurde. Das Fenster war beim letzten Programmlauf zu 20% geöffnet und der Antrieb hat seit
der letzten Ladung schon eine Strecke von 14300 „Kilometern“ zurückgelegt.
Die Gesamtreichweite, errechnet aus dem aktuellen Ladezustand und der zurückgelegten
Strecke, beträgt 47667 „Kilometer“. Wenn alles nach Plan verläuft, muss ich am
26.11.2017 den Akku wieder aufladen.
Gute Akkus – schlechte Akkus
Mein Kilometerzähler gibt natürlich nur einen groben Überblick über den Zustand der
Akku-Packs. Der Stromverbrauch der WinMatic ist nicht linear: Das Schließen eines
Fensters verbraucht mehr Strom als das Öffnen und beim Andrücken gibt es noch einen
Bonus on top. Auch die Verriegelung verbraucht unterschiedlich viel Strom und mit
Sicherheit nicht einfach exakt soviel wie das Öffnen und Schließen des Fensters. Ich
mache mir die Rechnung hier durchaus einfach.
Dazu kommt womöglich noch Wind, durch den das Fenster schwerer oder leichter zu
öffnen oder schließen ist, und auch die Parameter der CCU spielen eine Rolle: hohe
Geschwindigkeit oder hohe Andruckkraft bedeutet hohen Stromverbrauch.
Aber man kann immerhin Akku-Packs untereinander vergleichen und vor allem leicht
erkennen, wenn ein Pack unvermittelt seine Spannung verliert.
Während der Akku im Bad schon 14300 „Kilometer“ zurückkgelegt und eine
Restladung von 70% hat, ist dieser Kandidat schon nach 7240 „Kilometern“ bei 0 –
erkennbar daran, dass Strecke und Reichweite übereinstimmen. Und natürlich an der
Anzeige 0.00% beim Ladezustand, die ich hier nicht mitfotografiert habe.
Man kann in so einem Fall einen Kreuztest machen, also den Akku-Pack noch einmal frisch
aufladen und dann an einen anderen Antrieb setzen. Die Wahrscheinlichkeit ist aber doch
recht hoch, dass dieses Teil einfach das Ende seiner Lebensdauer erreicht hat und ersetzt
werden muss. Alles hat ein Ende, nur die
Wurst hat zwei.