Skript für Wecker mit Zeitintervall um den Weckzeitpunkt

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

Moderator: Co-Administratoren

Antworten
stewerks
Beiträge: 1
Registriert: 13.08.2019, 13:35

Skript für Wecker mit Zeitintervall um den Weckzeitpunkt

Beitrag von stewerks » 13.08.2019, 16:42

Hallo Community :D

Warum "wieder" ein Wecker Skript?
Ich habe kein passendes für meine Anforderungen gefunden bzw. keine anderen passenden Lösungen.
Meine Ausgangssituation ist, dass ich zu unterschiedlichen Zeiten aufstehe, möchte aber dennoch immer in ein warmes Bad kommen,
Licht soll entsprechend vor der Weckzeit angehen und das Rollo nicht vor der eigentlichen Weckzeit hochfahren (krach ^^) usw.

Was leistet das Skript?
  • "Beliebig viele" Wecker
  • Per (irgendeiner App) einfach eine Weckzeit definieren (in der Regel abends vorm schlafen gehen)
  • Einfaches Ein/Ausschalten
  • Wecker unterbrechen bzw. abbrechen und die damit Verbunden Aktionen
  • Und mir am wichtigsten: bereits vor der Weckzeit Aktionen wie "Heizen, Licht Dimmen..." vornehmen können, genauso danach ohne die Nutzung von (langen) Verzögerungen etc.
Das Skript besteht eigentlich aus 2 Skripten. Eins für die Initialisierung (kann immer wieder ausgeführt werden) und ein Skript,
welches sämtliche benötigten Systemvariablen entsprechend aktualisiert.

Pro Wecker werden 4 Systemvariablen erzeugt.
Insgesamt gibt es eine weitere Systemvariable die alle Wecker auflistet (sollte angepasst werden, Initial mit Wecker A und Wecker B eingerichtet).

Vollständige Einrichtung und detailiertere Beschreibung befindet sich im Quellcode.

Letztlich reagieren alle anderen Programme auf die Änderungen der Systemvariable "Wecker_NAME_Periode".
Wobei der Prefix "Wecker" angepasst werden kann und "NAME" aus den in der Weckerliste ergebenen Namenseinträgen besteht.

Beispiele für mein Anwendungsfall "Morgenroutine":

Code: Alles auswählen

Wenn "Wecker_NAME_Periode" im Wertebereich / mit Wert gleich -20 Minuten vor/nach Weckzeit [bei Änderung auslösen]
... Heizung an, Licht 30% ...

Wenn "Wecker_NAME_Periode" im Wertebereich / mit Wert gleich -10 Minuten vor/nach Weckzeit [bei Änderung auslösen]
... Licht 100% ...

Wenn "Wecker_NAME_Periode" im Wertebereich / mit Wert gleich 5 Minuten vor/nach Weckzeit [bei Änderung auslösen]
... Heizung aus, Licht aus ...
Falls man mal vergessen hat, seinen Wecker am Abend zu deaktivieren, ist es so auch möglich über den Status
"Wecker_NAME_State"
vorzeitig seinen Wecker abzubrechen und z. B. entsprechene Geräteeinstellungen rückgängig zu machen.

Quellcode Inline:

Code: Alles auswählen

! Script: Wecker Initialisierung ____________________________________________
! Version:  1.0
! Datum:    14.08.2019
! Autoren:  stewerks
! ***************************************************************************



! *** Anwendereinstellungen *************************************************

! Wenn Sie bereits vor der Initialisierung wissen, wieviele Wecker
! Sie benötigen, können Sie diese hier, Semikolon getrennt bereits 
! festlegen. Jeder Eintrag ist auch der Name für den jeweiligen Wecker.

string alarmNames = "A;B";

! Mögliche Anpassung des Prefix für die Systemvariablen um Kollisionen 
! mit anderen Scripten zu vermeiden

string prefix = "Wecker";

! Mögliche Anpassung des Zeitintervalls vor bzw. nach Auslösezeitpunkt
! in Minuten. Auch später über Syetemvariablen-Menü möglich.

integer timeLimitBeforeAlarm = 60;
integer timeLimitAfterAlarm = 60;


! ***************************************************************************



! *** Skript ****************************************************************

object svObject;
object svObjectList;

string weckerliste = dom.GetObject(prefix#"_List").ValueList();
string wecker;
integer i = 0;

svObject = dom.GetObject(prefix#"_List");
if (!svObject){
    svObjectList = dom.GetObject(ID_SYSTEM_VARIABLES);
    svObject = dom.CreateObject(OT_VARDP);
    svObjectList.Add(svObject.ID());
 
    svObject.Name(prefix#"_List");   
    svObject.ValueType(ivtInteger);
    svObject.ValueSubType(istEnum);
    svObject.ValueList(alarmNames);
    svObject.DPInfo("Ein Wecker pro Eintrag");
    svObject.ValueUnit("Wecker");
    svObject.Internal(false);
    svObject.Visible(true);
    svObject.State(1);
 
    dom.RTUpdate(0);
    WriteLine("Systemvariable: '"#prefix#"_List"#"' wurde erzeugt.");
} else {
    WriteLine("Systemvariable: '"#prefix#"_List"#"' bereits vorhanden. OK.");
}

foreach(wecker, weckerliste.Split(";"))
{
    string alarmName = weckerliste.StrValueByIndex(";",i);
    svObject = dom.GetObject(prefix#"_"#alarmName);
    if (!svObject){
        svObjectList = dom.GetObject(ID_SYSTEM_VARIABLES);
        svObject = dom.CreateObject(OT_VARDP);
        svObjectList.Add(svObject.ID());
 
        svObject.Name(prefix#"_"#alarmName);   
        svObject.ValueType(ivtBinary);
        svObject.ValueSubType(istBool);
        svObject.ValueName0("aus"); ! falsch = aus
        svObject.ValueName1("an"); ! wahr = an
        svObject.DPInfo("Wecker ein/ausschalten");
        svObject.ValueUnit("");
        svObject.Internal(false);
        svObject.Visible(true);
        svObject.State(false);
 
        dom.RTUpdate(1);
        WriteLine("Systemvariable: '"#prefix#"_"#alarmName#"' wurde erzeugt.");
    } else {
        WriteLine("Systemvariable: '"#prefix#"_"#alarmName#"' bereits vorhanden. OK.");
    }
    
    svObject = dom.GetObject(prefix#"_"#alarmName#"_Time");
    if (!svObject){
        svObjectList = dom.GetObject(ID_SYSTEM_VARIABLES);
        svObject = dom.CreateObject(OT_VARDP);
        svObjectList.Add(svObject.ID());
 
        svObject.Name(prefix#"_"#alarmName#"_Time");   
        svObject.ValueType(ivtInteger);
        svObject.ValueSubType(istEnum);
        svObject.ValueList("04:00;04:30;05:00;05:30;06:00;06:30;07:00;07:30;08:00;08:30;09:00;09:30;10:00;10:30;11:00;11:30;12:00");
        svObject.DPInfo("Weckzeit");
        svObject.ValueUnit("Uhr");
        svObject.Internal(false);
        svObject.Visible(true);
        svObject.State(1);
 
        dom.RTUpdate(0);
        WriteLine("Systemvariable: '"#prefix#"_"#alarmName#"_Time"#"' wurde erzeugt.");
    } else {
        WriteLine("Systemvariable: '"#prefix#"_"#alarmName#"_Time"#"' bereits vorhanden. OK.");
    }
    
    svObject = dom.GetObject(prefix#"_"#alarmName#"_State");
    if (!svObject){   
        svObjectList = dom.GetObject(ID_SYSTEM_VARIABLES);
        svObject = dom.CreateObject(OT_VARDP);
        svObjectList.Add(svObject.ID());
 
        svObject.Name(prefix#"_"#alarmName#"_State");   
        svObject.ValueType(ivtBinary);
        svObject.ValueSubType(istBool);
        svObject.ValueName0("unterbrochen"); ! falsch = unterbrochen
        svObject.ValueName1("gestartet"); ! wahr = gestartet
        svObject.DPInfo("Wecker starten/unterbrechen");
        svObject.ValueUnit("");
        svObject.Internal(false);
        svObject.Visible(true);
        svObject.State(false);
 
        dom.RTUpdate(0);
        WriteLine("Systemvariable: '"#prefix#"_"#alarmName#"_State"#"' wurde erzeugt.");
    } else {
        WriteLine("Systemvariable: '"#prefix#"_"#alarmName#"_State"#"' bereits vorhanden. OK.");
    }
    
    svObject = dom.GetObject(prefix#"_"#alarmName#"_Periode");
    if (!svObject){
        svObjectList = dom.GetObject(ID_SYSTEM_VARIABLES);
        svObject = dom.CreateObject(OT_VARDP);
        svObjectList.Add(svObject.ID());
 
        svObject.Name(prefix#"_"#alarmName#"_Periode");   
        svObject.ValueType(ivtFloat);
        svObject.ValueSubType(istGeneric);
     
        svObject.DPInfo("Zeitfenster um den Weckzeitpunkt");
        svObject.ValueUnit("Minuten vor/nach Weckzeit");
        svObject.ValueMin((-1) * timeLimitBeforeAlarm);
        svObject.ValueMax(timeLimitAfterAlarm);
        svObject.Internal(false);
        svObject.Visible(true);
        svObject.State(0);
 
        dom.RTUpdate(0);
        WriteLine("Systemvariable: '"#prefix#"_"#alarmName#"_Periode"#"' wurde erzeugt.");
    } else {
        WriteLine("Systemvariable: '"#prefix#"_"#alarmName#"_Periode"#"' bereits vorhanden. OK.");
    }
    
    i = i+1;
}

Code: Alles auswählen

! Script:   Wecker __________________________________________________________
! Version:  1.0
! Datum:    14.08.2019
! Autoren:  stewerks
! ***************************************************************************



! *** Beschreibung **********************************************************

! Ein Weckerprogramm für nahezu beliebig viele Wecker.
! - Einfaches ein/ausschalten möglich
! - Weckzeit aus veränderbarer Liste einfach wählbar
! - Unterbrechungsfunktion
! - Auslösezeitpunkte vor- bzw. nach der eigentlichen Weckzeit
!   um z. B. eine Heizung oder Licht einfach vor der eigentlichen
!   Weckzeit einzuschalten.

! ***************************************************************************



! *** Einrichtung / Installation / Bedienung ********************************

! ---------------------------------------------------------------------------
! Kapitel 0 - Namen und Definitionen
! ---------------------------------------------------------------------------
! Im Folgenden werden Sie die Zeichenkette: "WECKER" vorfinden.
! WECKER steht symbolisch für den von Ihnen gewählten Variablen-Prefix Namen.
! Standardmäßig ist dieser "Wecker", kann aber im Skript geändert werden.

! Im Folgenden werden Sie die Zeichenkette: "NAME" vorfinden.
! NAME steht symbolisch für die Einträge in Ihrer eigenen 
! "WECKER_List" - Systemvariable.

! ---------------------------------------------------------------------------
! Kapitel 1 - Initialisierung von Systemvariablen
! ---------------------------------------------------------------------------
! Erstellen Sie ein neues Programm, z. B. mit dem Namen "Wecker-Init".
! Kopieren Sie dort das Wecker-Initialisierungs-Skript hinein und passen
! es bei Bedarf an. Es wird lediglich für das Erzeugen von Systemvariablen
! benötigt. Nähres dazu in dem Skript.
! Führen Sie anschließend das Programm aus.

! ---------------------------------------------------------------------------
! Kapitel 2 - Einrichtung des Weckerprogramms
! ---------------------------------------------------------------------------
! Erstellen Sie ein neues Programm, z. B. mit dem Namen "Wecker".
! Kopieren Sie dieses Skript in das Programm.
! Dieses Skript muss jede Minute ausgeführt werden, keine Sorge, es ändert 
! nur Systemvariablen, sodass das Ihr System weiterhin schnell agiert.
! Nutzten Sie hierfür z. B. das Zeitmodul der CCU mit ganztägiger Ausführung
! und dem Zeitinterfall von 1 Minute.

! ---------------------------------------------------------------------------
! Kapitel 3 - Nutzung eines Weckers
! ---------------------------------------------------------------------------
! Um den Wecker zu nutzen, verwenden Sie die 
! Systemvariable "WECKER_NAME_Periode".
! Sie können diese Variable nun so nutzen, das z. B. bei "Änderung auslösen"
! und 20 Minuten vor oder nach der eigentlichen Weckzeit 
! ihr eigenes Programm ausgeführt wird.
! Standardmäßig ist der Min-Wert und Max-Wert dieser Systemvariable auf 
! jeweils 60 Minuten eingestellt, d. h. 60 Min vor der eigentlichen
! Weckzeit, und 60 Minuten danach. 
! Diese Variable wird nur in diesem Zeitintervall aktualisiert und auch
! nur, wenn der Wecker nicht unterbrochen worden ist.

! ---------------------------------------------------------------------------
! Kapitel 4 - Einstellen der Weckzeit
! ---------------------------------------------------------------------------
! Um ein bequemes Einstellen der Weckzeit zu ermöglichen, wird diese als
! Liste ausgeliefert, z. B. "10:00;10:30;11:55" und in der
! Systemvariable "WECKER_NAME_Time" gespeichert.
! Mit entsprechenden Apps/Erweiterungen lassen sich Systemvariablen per
! grafischer Oberfläche ändern. Leider nicht mit der Web-Oberfläche der
! Homematic selbst.
! Sie können in den Systemvariablen-Einstellungen die möglichen Werte dieser 
! Liste auf Ihre Bedürfnisse abändern. Format: HH:MM
! Beachten Sie, dass nach dem letzten Eintrag in der Liste 
! kein Simikolon folg!

! ---------------------------------------------------------------------------
! Kapitel 5 - Wecker Ein/Ausschalten
! ---------------------------------------------------------------------------
! Um den Wecker ein- bzw. auszuschalten ändern Sie einfach den Wert der
! Systemvariable "WECKER_NAME" auf an(true)/aus(false).

! ---------------------------------------------------------------------------
! Kapitel 6 - Wecker Unterbrechen
! ---------------------------------------------------------------------------
! Um den Wecker zu unterbrechen ändern Sie einfach den Wert der
! Systemvariable "WECKER_NAME_State".
! Wurde der Wecker unterbrochen, wird die Systemvariable
! "WECKER_NAME_Periode" nicht mehr aktualisiert.
! Erst ein Fortsetzen, also WECKER_NAME_State: gestartet bzw. nach Ablauf 
! der Zeit von MaxValue von "WECKER_NAME_Periode" plus Weckzeit wird 
! die Systemvariable "WECKER_NAME_Periode" wieder aktualisiert 
! (also mit Beginn eines neuen Weckzyklus).
! Die Systemvariable "WECKER_NAME_State" wird ebenfalls nach Ablauf
! des Weck-Zeitintervalls wieder gestartet.

! ---------------------------------------------------------------------------
! Kapitel 7 - Hinzufügen weiterer Wecker
! ---------------------------------------------------------------------------
! Um weitere Wecker hinzuzufügen, passen Sie die Systemvariable
! "WECKER_List" an, z. B. "Alarm1;Alarm2;Alarm3".
! Beachten Sie, dass nach dem letzten Eintrag in der Liste 
! kein Simikolon folg!
! Führen Sie anschließend das Initialisierungsskript erneut aus.
! Dieses überschreibt keine bestehenden Variablen.

! ---------------------------------------------------------------------------
! Kapitel 8 - Hinzufügen weiterer Wecker
! ---------------------------------------------------------------------------
! Falls Sie erstellte Wecker löschen wollen, entfernen Sie diese aus
! der Systemvariable "WECKER_List" und löschen Sie die nicht mehr
! benötigten Systemvariablen manuell.

! ---------------------------------------------------------------------------
! Kapitel 9 - Namenskonflikte Lösen
! ---------------------------------------------------------------------------
! Der Prefix: "WECKER" kann nach Bedarf ebenfalls konfiguriert werden.
! Siehe dazu Anwendereinstellungen in diesem Skript bzw. im Initialisierungs-
! Skript.
 
! ***************************************************************************



! *** Anwendereinstellungen *************************************************

! Mögliche Anpassung des Prefix für die Systemvariablen um Kollisionen 
! mit anderen Scripten zu vermeiden

string prefix = "Wecker";

! ***************************************************************************



! *** Skript ****************************************************************

string wecker;
string weckerliste = dom.GetObject(prefix#"_List").ValueList();
integer i = 0;
integer error = 0;

foreach(wecker, weckerliste.Split(";"))
{
    string alarmName = weckerliste.StrValueByIndex(";",i);

    ! Falls die benötigten Wecker-Systemvariablen nicht exitieren, wird für den entsprechenden Wecker
    ! in der "Wecker_List" dieses Skript nicht ausgeführt.
    ! Da kein break/continue zur Verfügung steht, wird hier mit einer zusätzlichen Kontroll-Variable gearbeitet
    ! Rücksetzen der Error-Variable für jeden Schleifendurchlauf
    
    error=0;

    if ((!dom.GetObject(prefix#"_"#alarmName)) && (error == 0))
    {
        error = 1;
    }
    if (!dom.GetObject(prefix#"_"#alarmName#"_Time"))
    {
        error = 1;
    }
    if ((!dom.GetObject(prefix#"_"#alarmName#"_State")) && (error == 0))
    {
        error = 1;
    }
    if ((!dom.GetObject(prefix#"_"#alarmName#"_Periode")) && (error == 0))
    {
        error = 1;
    }

    ! Wenn alle notwendigen Systemvariablen vorhanden sind
    if(error == 0){
        ! Zeit ermitteln
        string timeList = dom.GetObject(prefix#"_"#alarmName#"_Time").ValueList();
        integer selection = dom.GetObject(prefix#"_"#alarmName#"_Time").Value();
        string alarmSelection = timeList.StrValueByIndex(";",selection);
        boolean alarmState = dom.GetObject(prefix#"_"#alarmName).Value();
        
        ! Wenn der Wecker aktiv ist, führe nachfolgendes aus
        ! Format der Einträge muss sein: HH:MM
        if(alarmState == 1){
            time now = system.Date("%Y-%m-%d %H:%M:%S").ToTime().ToInteger();  
            time alarm = system.Date("%Y-%m-%d "#alarmSelection#":00").ToTime().ToInteger();
            
            ! Aktualisieren der Periode im Zeitintervall: Weckzeit-Min bis Weckzeit+Max.
            ! Falls Wecker unterbrochen, keine weitere Aktualisierung. Unterbrechung wird nach Weckzeit+Max aufgehoben.
            integer min = dom.GetObject(prefix#"_"#alarmName#"_Periode").ValueMin().ToInteger() * 60;
            integer max = dom.GetObject(prefix#"_"#alarmName#"_Periode").ValueMax().ToInteger() * 60;
 
            if(min < 0){
                min = (-1) * min;
            }
            if((now >= (alarm - min)) && (now <= (alarm + max))){
                if(dom.GetObject(prefix#"_"#alarmName#"_State").Value() == 1){
                    integer diff = 0;
                    diff = (now - alarm) / 60;
                    if(dom.GetObject(prefix#"_"#alarmName#"_Periode").Value() != diff){
                        dom.GetObject(prefix#"_"#alarmName#"_Periode").State(diff);
                    }
                }
            } else {
                ! Zurücksetzen einer Weckerunterbrechung
                ! Wird der Status extern auf "gestoppt/unterbrochen" gesetzt, wird dieser
                ! nach der Weck-Zeitspanne hier wieder gestartet um erneut wecken zu können.
                ! Diese Variable hat für den Wecker selbst keine weitere Bedeutung, allerdings können
                ! so Programme die den Wecker benutzen Ihre Ausführung stoppen/unterbrechen.
                if(dom.GetObject(prefix#"_"#alarmName#"_State").Value() != 1){
                    dom.GetObject(prefix#"_"#alarmName#"_State").State(1);
                }
            }
        }
    } else {
        WriteLine("Systemvariablen für den Wecker "#alarmName#" fehlen. Eine neue Ausführung des Initialisierungsskript ist notwendig.");
    }
    
    i = i+1;
}



Quellcode Download:
wecker-init.hm-script.txt
(5.59 KiB) 9-mal heruntergeladen
wecker.hm-script.txt
(10.18 KiB) 8-mal heruntergeladen
Gruß
Stefan

Antworten

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