da ich mehrere Rolladenaktoren mein Eigen nenne ist es mir wie vielen anderen hier ein ständiges Ärgernis geworden zu beobachten, dass bei Verbindungsfehlern meine Programme im Prinzip ihren Zweck nicht erfüllen. Man stelle sich vor man ist im Urlaub und wegen eines blöden Verbindungsfehlers bleiben die Rolläden oben - Einbrecher Herzlich Willkommen.
Ich habe hier von jemandem gelesen, der regelmäßig alle paar Minuten erneut den Status seiner Geräte setzt wenn sie nicht den gewünschten Wert haben. Die Grundidee dahinter fand ich nicht schlecht, aber das verhindert gewissermaßen, dass man die Komponenten auch mal von Hand bedient, denn dann würden sie nach 5 minuten (oder wann immer das Skript läuft) wieder zurückfahren - also auch nicht ideal.
Ich möchte hier nun meine Lösung teilen, die ich seit einigen Wochen im Einsatz habe und endlich zu meiner Zufriedenstellung funktioniert:
Meine Grundidee ist, für jedes Gerät eine Systemvariable mit dem Namen CCU2Wert_<Kanal ID> anzulegen. Im jeweiligen Programm muss man dann neben dem Gerät selbst immer auch diese Variable setzen. Diese Variable speichert sozusagen den Wert, den das Gerät eigentlich nun aufgrund der Programmierung in der CCU2 haben sollte. Wenn eine Störung auftritt (und nur dann!), wird versucht das Gerät wieder auf genau diesen Wert zu setzen. Es empfiehlt sich, die Variablen kanalbezogen zu definieren damit man sie in den Programmen leichter findet.
Zum Einsatz kommt eine Abwandlung des bekannten Servicemeldungsskripts von Christian Luetges. Unterschied ist bei mir nur, dass ich das ganze in ein Skript gepackt habe, denn ich persönlich habe noch nicht den Vorteil gesehen es aufzuteilen und bin eher ein Freund davon die Anzahl der Programme überschaubar zu halten. Dieses Skript fragt dann alle 5 Minuten ab, ob es Geräte gibt, für die "Kommunikation war gestört" gemeldet wurde. Wenn dies der Fall ist, wird nicht nur die Meldung einfach bestätigt, sondern versucht, das Gerät auf den Wert zu setzen, der in der dazugehörigen CCU2Wert_* Variablen drinsteht. Zusätzlich schreibe ich auch noch ein Mail darüber, dass die Kommunikation gestört war, so hat man ein bisschen im Überblick wie oft das passiert.
Code: Alles auswählen
! Skript zur Bestätigung der Servicemeldungen und Retriggern der letzten Aktion
! (Anlehnung an http://www.christian-luetgens.de/homematic/funkstoerungen/servicemeldungen/Servicemeldungen.htm)
string itemID;
string address;
object aldp_obj;
string channel;
var newstate;
var curstate;
string stdout;
string stderr;
string cmd;
! Versuch der Kommunikation mit dem Gerät bei "Kommunikation ist gestört"
foreach(itemID, dom.GetObject(ID_DEVICES).EnumUsedIDs()) {
address = dom.GetObject(itemID).Address();
aldp_obj = dom.GetObject("AL-" # address # ":0.UNREACH");
if (aldp_obj) {
if (aldp_obj.Value()) {
foreach (channel, dom.GetObject(itemID).Channels().EnumUsedIDs()) {
curstate = dom.GetObject(channel).State();
}
}
}
}
! Prüfen auf "Kommunikation war gestört"
! Für jedes Gerät muss eine Systemvariable mit dem Namen "CCU2Wert_<CHANNEL>" existieren
! In den jeweiligen Programmen oder Skripten muss dann immer neben dem Gerät selbst auch die Variable auf den Zielwert gesetzt werden
! Beispiel: CCU2Wert_KEQ4711463:1 = 1
foreach(itemID, dom.GetObject(ID_DEVICES).EnumUsedIDs()) {
address = dom.GetObject(itemID).Address();
aldp_obj = dom.GetObject("AL-" # address # ":0.STICKY_UNREACH");
if (aldp_obj) {
if (aldp_obj.Value()) {
foreach (channel, dom.GetObject(itemID).Channels().EnumUsedIDs()) {
if (dom.GetObject("CCU2Wert_" # dom.GetObject(channel).Address()))
{
newstate = dom.GetObject("CCU2Wert_" # dom.GetObject(channel).Address()).State();
dom.GetObject(channel).State(newstate);
cmd = "/etc/config/addons/email/email 02 \"" # dom.GetObject(channel).Name() # "\" " # newstate # " " # dom.GetObject(channel).State();
system.Exec(cmd, &stdout, &stderr);
aldp_obj.AlReceipt();
}
}
}
}
}
VG
Bastian