Mein Wecker im FHEM TabletUI

Heute möchte ich mal meine Umsetzung eines Weckers im FHEM TabletUI vorstellen. Eine der ersten Anwendungen, die ich im TabletUI realisiert und quasi täglich nutze. Wahrscheinlich gibt es im Moment noch weitere Möglichkeiten der Umsetzung, da ja einige neue Widgets hinzu gekommen sind. Außerdem hat das von mir verwendete Modul Residents mittlerweile auch die Option einer Weckfunktion eingebaut. Diese habe ich mir aber bisher nicht genauer angesehen.

Das Szenario meiner Weckfunktion

Die Aktionen, die beim morgendlichen Wecken ausgeführt werden sollen, steuere ich mittels der Residents Funktion und dem Status „awoken“. Mit einem Notify rufe ich beim Erreichen des Status „awoken“ eine Funktion auf, in der alle Aktionen gestartet werden. So werden dann die Rolladen hoch  gefahren bzw. das Licht eingeschaltet, wenn es noch dunkel ist. Im Bad und in der Küche werden die Sonos Player gestartet und mit etwas Zeitverzögerung wird dann auch der Receiver im Wohnzimmer gestartet. Über die Urlaubssteuerung werden die Weckzeiten dann noch deaktiviert.

Normalerweise könnte man eine solche Funktionalität recht einfach mittels WeekdayTimer Modul realisieren. Sofern sich die Weckzeiten aber täglich ändern könnten oder man immer wieder mal unterschiedliche Weckzeiten haben möchte, müssten man immer wieder die Definition des Timers ändern. Diese Änderung habe ich nun mit meiner Weckfunktion realisiert. Durch das Stellen des Weckers wird jedesmal der entsprechende WeekdayTimer modifiziert.

Wecker mit aufgeklappten Timer Optionen

Wecker mit aufgeklappten Timer Optionen

Vorbereitungen für die Weckerfunktion

Zur Speicherung der aktuellen Weckzeiten habe ich ein Dummy verwendet. Damit können dann auch immer die aktuellen Zeiten recht einfach dargestellt werden. Für jeden Tag hat dieser Dummy ein eigenes Reading (z.B. wzMontag), in dem die entsprechende Uhrzeit gespeichert wird.

define duWeckzeit DUMMY

Die Readings werden normalerweise automatisch erstellt, sobald ein „setreading“ durchgeführt wird. Damit man alle Readings direkt nach der Definition sehen kann, sollte man idealerweise für jeden Tag die Funktion aus der FHEM Oberfläche aufrufen (Bsp. für Montag):

setreading duWeckzeit wzMontag 09:00

Nun wird der WeekdayTimer definiert, der die eigentliche Zeitsteuerung übernimmt, also zur entsprechenden Zeit den Status „awoken“ beim Residents Device setzen soll. Auf die eigentliche das Residents Modul werde ich hier nicht näher eingehen, sondern nur kurz meine Definition darstellen:

define gr_Bewohner RESIDENTS
define Aufstehen WeekdayTimer gr_Bewohner 0|09:00|awoken 1|08:00|awoken 2|08:00|awoken 3|08:00|awoken 4|08:00|awoken 5|08:00|awoken 6|09:00|awoken (ReadingsVal("duUrlaub","state","ja") eq "nein")

Zur Erläuterung des WeekdayTimer möchte ich auf den entsprechende Wiki-Erläuterung verweisen. Mit meine Definition sorge ich dafür, dass mein Device „gr_Bewohner“ zu den definierten Zeiten auf den Status „awoken“ gesetzt wird. Die Definitionen der Tage beginnen mit 0 beim Sonntag. Also habe ich für das Wochenende die Weckzeiten auf 09:00 Uhr und an den Wochentagen auf 8:00 gesetzt.

Dummy für die Weckzeiten

Dummy für die Weckzeiten

Nun benötigen wir nur noch ein Device, welches wir für die Darstellung des Weckers im TabletUI nutzen können. Theoretisch hätte man den bereit vorhandenen Dummy „duWeckzeit“ nutzen können. Ich hatte mich aber entschieden, hierfür ein eigenes Dummy-Device anzulegen:

define duWeckerTabUI DUMMY

Diesem Dummy habe ich die Readings „Tag“, „Stunde“, „Minute“ und „Timer“ verpasst. Wie oben beschrieben, können diese zunächst wieder von Hand angelegt werden, damit sie alle vorhanden sind. Die Readings „Tag“, „Stunde“ und „Minute“ dienen dazu, die entsprechenden Werte im TabletUI darzustellen. Mit „Timer“ besteht die Möglichkeit, unterschiedliche Wecker zu nutzen. Hierzu müssen dann zusätzliche notify-Abfragen und Funktionen geschrieben werden. Ich habe aktuell nur den Wecker zum Aufstehen in Betrieb.

Dummy für die Verbindung mit dem TabletUI Widgets

Dummy für die Verbindung mit dem TabletUI Widgets

Aktionen für die Weckfunktionen und die Steuerung aus dem TabletUI

Nachdem die Vorbereitungen soweit erledigt sind, kümmern wir uns nun um die Steuerfunktionen. Beginnen wir hierzu mit der eigentlichen Weckfunktion. Sobald das Resident Device „gr_Bewohner“ den Status „awoken“ erhält, wird die Funktion für die Aktionen beim Aufstehen aufgerufen. Dies geschieht mit folgendem notify.

define notAufstehen NOTIFY gr_Bewohner:awoken {Aufstehen($we)}

Mit der Variablen $we gebe ich der Funktion noch mit, ob wir gerade Wochenende bzw. einen Feiertag haben. Die Funktion sind dann als Template wie folgt aus:

#
#Alle Funktionen für das Aufstehen
#
sub Aufstehen($)
{
   my ($we) = @_;

   #hier können alle Schaltaktionen aufgerufen werden, die beim Aufstehen zu starten sind
   fhem("set Alle_Rolladen on");
}

Jetzt müssen wir nur noch die Funktion zum Stellen des Weckers also zum Eintragen der richtigen Werte in den Dummy Wecker und zum Ändern des WeekdayTimer definieren. Zunächst definieren wir den notify für die Stellen-Funktion, die aus dem TabletUI aufgerufen wird.

define notWeckerStellen notify duWeckerTabUI:stellen {WeckerStellen()}

Die Funktion sieht bei mir wie folgt aus:


#
# Hilfsfunktion für den Wecker: Stellt den "Wecker Dummy", der alle Weckzeiten enthält auf Basis der Einstellung im TabUI
#
sub WeckerStellen()
{
   my $timer = ReadingsVal("duWeckerTabUI", "Timer", "Aufstehen");
   my $Tag = ReadingsVal("duWeckerTabUI","Tag","Reset");
   my $Zeit = sprintf("%02d",ReadingsVal("duWeckerTabUI","Stunde","09")).":".sprintf("%02d",ReadingsVal("duWeckerTabUI","Minute","00"));

   #jeden Wochentag zur gleichen Zeit wecken
   if($Tag eq "Wochentag")
   {
      fhem("setreading duWeckzeit wzMontag ".$Zeit);
      fhem("setreading duWeckzeit wzDienstag ".$Zeit);
      fhem("setreading duWeckzeit wzMittwoch ".$Zeit);
      fhem("setreading duWeckzeit wzDonnerstag ".$Zeit);
      fhem("setreading duWeckzeit wzFreitag ".$Zeit);
   }
   elsif ($Tag eq "Wochenende") #Weckzeit für Wochenende
   {
      fhem("setreading duWeckzeit wzSamstag ".$Zeit);
      fhem("setreading duWeckzeit wzSonntag ".$Zeit);
   }
   elsif ($Tag eq "Reset") #Default Weckzeiten setzen
   {
      if($timer eq "Aufstehen")
      {
         fhem("setreading duWeckzeit wzMontag 08:00");
         fhem("setreading duWeckzeit wzDienstag 08:00");
         fhem("setreading duWeckzeit wzMittwoch 08:00");
         fhem("setreading duWeckzeit wzDonnerstag 08:00");
         fhem("setreading duWeckzeit wzFreitag 08:00");
         fhem("setreading duWeckzeit wzSamstag 09:00");
         fhem("setreading duWeckzeit wzSonntag 09:00");
      }
      elsif($timer eq "?") #Funktion für weitere Timer
      {
          # fhem('modify WeekdayTimer oder at');
      }
   }
   else #Weckzeit für einen bestimmten Tag
   {
      fhem("setreading duWeckzeit wz".ReadingsVal("duWeckerTabUI","Tag","Montag")." ".$Zeit);
   }
   
   if($timer eq "Aufstehen") #WeekdayTimer für Aufstehen modifizieren
   {
      fhem("modify Aufstehen gr_Bewohner 0|".ReadingsVal("duWeckzeit","wzSonntag","09:00")."|awoken 1|".ReadingsVal("duWeckzeit","wzMontag","09:00")."|awoken 2|".ReadingsVal("duWeckzeit","wzDienstag","09:00")."|awoken 3|".ReadingsVal("duWeckzeit","wzMittwoch","09:00")."|awoken 4|".ReadingsVal("duWeckzeit","wzDonnerstag","09:00")."|awoken 5|".ReadingsVal("duWeckzeit","wzFreitag","09:00")."|awoken 6|".ReadingsVal("duWeckzeit","wzSamstag","09:00").'|awoken (ReadingsVal("duUrlaub","state","ja") eq "nein")');
   }
   elsif($timer eq "?") #Modify Funktion für weitere Timer
   {
      # fhem('modify WeekdayTimer oder at');
   }

   fhem("save config");
}

Wecker im TabletUI darstellen

Nun benötigen wir nur noch die Darstellung des Weckers im TabletUI sowie die entsprechenden Aufrufe. Für die Auswahl der Tage sowie der Timer wird eine Listbox verwendet. Mit einem Pushbutton wird die Funktion zum Stellen des Weckers umgesetzt. Für das Einstellen der Stunden und Minuten habe ich das Lautstärke Widget genutzt. Die Definition des Weckers sieht dann wie folgt aus:

<li data-row="1" data-col="2" data-sizex="3" data-sizey="2">
<header>Weckzeit stellen</header>
<div class="container narrow">
   <div class="container">
      <div data-type="select" data-device="duWeckerTabUI" data-get="Tag" data-set="Tag" data-cmd="setreading"
         data-list="" data-items='["Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag","Sonntag","Wochenende","Wochentag","Reset"]'
         class="w3x">
      </div>
      <div data-type="select" data-device="duWeckerTabUI" data-get="Timer" data-set="Timer" data-cmd="setreading"
         data-list="" data-items='["Aufstehen","Rolladen hoch","Rolladen runter"]' class="w3x">
      </div>
      <div class="container narrow">
         <div data-type="push" data-device="duWeckerTabUI" data-cmd="set" data-set-on="stellen" class="cell"></div>
         <div data-type="label" class="narrow">Stellen</div>
      </div>
   </div>
</div>
<div class="container narrow">
   <div class="container inline right-space narrow">
      <div data-type="volume" data-device="duWeckerTabUI" data-get="Stunde" data-set="Stunde" data-cmd="setreading" 
         data-min="0" data-max="24"></div>
      <div data-type="label" class="" style="margin-top:-40px">Stunde</div>
   </div>
   <div class="container inline narrow">
      <div data-type="volume" data-device="duWeckerTabUI" data-get="Minute" data-set="Minute" data-cmd="setreading"
         data-min="0" data-max="60"></div>
      <div data-type="label" class="" style="margin-top:-40px">Minute</div>
   </div>
</div>
</li>
Wecker mit aufgeklappten Tagen

Wecker mit aufgeklappten Tagen

Damit man nun noch sehen kann, welche Zeiten gerade eingestellt sind, gibt es noch einen Bereich zur Darstellung der Werte aus dem Dummy „duWeckzeit“.

<li data-row="1" data-col="4" data-sizex="2" data-sizey="2">
<header>Aktuelle Weckzeiten</header>
<table width="100%">
<tr>
   <td class="big right">Montag</td>
   <td><div data-type="label" data-device="duWeckzeit" data-get="wzMontag" class="big"></div></td>
</tr>
<tr>
   <td class="big right">Dienstag</td>
   <td><div data-type="label" data-device="duWeckzeit" data-get="wzDienstag" class="big"></div></td>
</tr>
<tr>
   <td class="big right">Mittwoch</td>
   <td><div data-type="label" data-device="duWeckzeit" data-get="wzMittwoch" class="big"></div></td>
</tr>
<tr>
   <td class="big right">Donnerstag</td>
   <td><div data-type="label" data-device="duWeckzeit" data-get="wzDonnerstag" class="big"></div></td>
</tr>
<tr>
   <td class="big right">Freitag</td>
   <td><div data-type="label" data-device="duWeckzeit" data-get="wzFreitag" class="big"></div></td>
</tr>
<tr>
   <td class="big right">Samstag</td>
   <td><div data-type="label" data-device="duWeckzeit" data-get="wzSamstag" class="big"></div></td>
</tr>
<tr>
   <td class="big right">Sonntag</td>
   <td><div data-type="label" data-device="duWeckzeit" data-get="wzSonntag" class="big"></div></td>
</tr>
</table> 
</li>

So, dann hoffe ich mal, dass ich nun alle Definitionen und Funktionen vollständig und richtig in den Artikel übertragen habe. Bei der Darstellung des Weckers muß man wahrscheinlich selbst noch ein wenig herum probieren. Eigentlich ist der Button zum Stellen ein wenig zu hoch positioniert und man erwischt schnell eine der Listboxen. Viel Spaß mit den Anregungen und natürlich nehme ich gerne auch wieder Verbesserungsvorschläge und Hinweise zu Fehlern entgegen ;-).

20 comments

  1. Hallo,

    ich lese mit Begeisterung deinen Blog und finde die Idee mit dem Wecker echt gut.

    Leider funktioniert es nicht.

    Einmal musste das „subAufstehen($)“ wohl das „sub Aufstehen($)“ heißen.

    Beim Definieren von „define notWeckerStellen&amp;amp;nbsp;duWeckerTabUI:stellen {WeckerStellen()}“, bekomme ich folgende Fehlermeldung:

    Usage: define
    Unknown command amp, try help.
    Unknown command amp, try help.
    Unknown command nbsp, try help.
    Unknown command duWeckerTabUI:stellen, try help.

    Außerdem muss es im index_setup.html „duWeckzeit“ und nicht „Weckzeit“ heßen, ein Alise hat nicht funktioniert.

    Wenn du hälfen könntest, wäre das echt klasse 🙂

    Grüß
    Kay

  2. Vielen Dank für die Hinweise, die ich im Text direkt mal angepasst habe. Das kommt davon, wenn man versucht, bisher nicht eingehaltene eigene Namenskonventionen, umzusetzen und dann vergisst, den Code überall anzupassen.

    Darüber hinaus hat es wohl auch beim Kopieren ein paar Probleme gegeben. Die „amp“ Stellen müssen natürlich weg. Der aktuelle Code sollte nun hoffentlich richtig sein.

  3. Vielen Dank für deine Korrektur, leider hat es wieder nicht funktioniert, habe aber selber festgestellt, das bei: „define notWeckerStellen duWeckerTabUI:stellen {WeckerStellen()}“, das NOTIFY fehlt.

  4. Hallo Jürgen,

    danke für deine Arbeit.
    Leider funktioniert bzw. stellt sich bei mir keine Uhrzeit ein wenn ich auf der UI-Oberfläsche eine einstelle.
    Woran könnte das liegen?

  5. Die erste Frage wäre nun, wo genau das Stellen nicht funktioniert. Wie sieht zum Beispiel der Dummy aus, nachdem die Uhrzeit im Tablet UI eingestellt wurde. Steht im Dummy „duWeckerTabUI“ der richtige Wert. Falls nicht, dann ist evtl. ein Fehler bei dem entsprechenden Button im TabUI Code. Oder wird der Weekday-Timer nicht richtig angepasst? Oder gibt es noch andere Probleme?

  6. Hallo Jürgen,

    schöne Beschreibung und nützliche Funktion. Wenn ich mir jedoch noch abgesehen von o.g. Anmerkungen noch etwas erlauben dürfte:

    1. hier das richige notify:

    define notWeckerStellen notify duWeckerTabUI:stellen {WeckerStellen()}

    2. Evtl wäre es passed für noch nicht so Fhem versierte User zu erklären wie und wo die SUBs reinkommen, das ganze sollte man evtl der Reihenfolge nach verbessern, damit diese nachher nicht verzweifeln 🙂

    Ansonsten klasse Modul und vor allem endlich mal wieder nützlich,

    danke und ich freue mich auf Deine nächsten Tutorials, die ich gerne weiter verfolge,
    Grüsse, Ralf

  7. Danke für den Hinweis und die Tipps. Ich dachte, dass ich den notify schon im Text angepasst hatte ;-). Bezüglich des Hinweis für „Neueinsteiger“ werde ich mir mal überlegen, ob ich nicht mal einen entsprechenden Einsteiger-Text erstelle. Allerdings gibt es hier ja auch zahlreiche Hilfestellungen über das Wiki oder das Forum. Für das TabUI habe ich einen solchen Text nahezu fertig und werde ihn bald – evtl. als Serie veröffentlichen können.

  8. Hallo Jürgen,

    erstmal vielen Dank für das detailierte Teilen deines Wissens!!! Mein TabUI sieht mitterweile schon recht brauchbar aus, dank vieler Deiner Ideen und Beschreibungen. Ich bin jedoch einer dieser von Ralf erwähnten Einsteiger und bin mir nun nicht ganz sicher ob es richtig war die SUBs unter My_Utils zu kopieren?!?
    Im TabUI bekomme ich den Wecker angezeigt und kann auch meine Weckzeiten stellen, jedoch passiert zu den gestellten Uhrzeiten nichts…
    Befinde mich also zur Zeit auf Fehlersuche und vermute das ich die SUBs vielleicht doch nicht in MyUtils hätte kopieren müssen?!?!?

    Über kurze Rückmeldung würde ich mich sehr freuen!

    LG

    Torsten

  9. Hallo Torsten,
    die Subs – also alle Funktionen – müssen in die myutils-Datei eingefügt werden. Allerdings muß der Name dieser Dateien immer mit 99_ beginnen. Sonst werden sie nicht geladen. Die Datei muss also 99_myutils.pm heißen. Für eine erste Anlage sollte die vorhandene Datei myUtilsTemplate.pm genommen werden und diese unter dem Namen 99_myutils.pm gespeichert werden. Dann sind auch die notwendigen Initialsierungen enthalten. Weitere Infos findet man auch im FHEM-Wiki gut erläutert.

  10. Hallo Jürgen,

    vielen Dank für die schnelle Antwort und die Hilfe, sowie den Link, das war schonmal sehr hilfreich. Leider bräcuhte ich aber jetzt dochnochmal deinen Tipp, denn ich finde den Fehler leider nicht.
    Der Wecker wird im TabUi gestellt und auch in der Ansicht werden die neu gestellten Zeiten gezeigt.
    In FHEM bleibt der Weekdaytimer „Aufstehen“ auf inactive, der duWeckerTabUI erhält in den Readings die richtigen Werte, duWeckzeit erhält ebenfalls für die Wochentage alle Uhrzeiten, lediglich state bleibt auf ???.
    Als Aktion habe ich das schalten von zwei Lampen und einschalten des Radios gesetzt (fhem(„set Eingang on“); fhem(„set Kueche on“); fhem(„set SRadio on“); .
    Leider tut sich aber rein garnichts…

    Was habe ich vergessen, bzw. falsch gemacht?

    Liebe Grüße

    Torsten

  11. Hallo,
    ich glaube der duUrlaub fehlt in der Anleitung. Lässt sich das ganze noch mit einem Anwesenheitstatus unter Residents erweitern? Man will ja nicht, dass die Aktionen ausgeführt werden wenn man gar nicht zuhause ist

  12. Stimmt, den Dummy „duUrlaub“ habe ich nicht näher erläutert. Dieser Dummy wird bei mir entweder über einen Kalender oder per „Knopf“ gesetzt, wenn ich längere Zeit nicht im Haus bin. Dann werden nicht die Weckzeiten genutzt sondern extra Funktionen für den Urlaub. Im Prinzip könnte man natürlich auch ein Status aus Residents entsprechend nutzen. Man benötigt im Prinzip eine Bedingung, mit der der WeekdyTimer aktiviert bzw. deaktiviert wird.

  13. Hallo Jürgen,

    danke für diese tolle Anleitung!
    Derzeit versuche ich, fhem Neuling diese zu installieren!
    meine hoffentlich nicht zu dumme Frage zum Punkt TabletUI

    Erfolgt die Anpassung in der Index.html Datei oder muss/kann eine eigene „Seite“ (z.b. Wecker.html) erstellt werden und wo füge ich den Schnipsel ein?
    Sind das eventuell zwei Dateien?
    Habe ich was überlesen?

    Vielen Dank für Deine Bemühungen.

    Netten Gruss aus Neuss am Rhein

  14. Den Codeschnipsel kannst du auf irgendeiner Seite einbauen. In der Anleitung ist ja auch das umschließende

    <li data-row="ZEILE" data-col="SPALTE" data-sizex="2" data-sizey="2">

    aufgeführt. Bei mir habe ich den Wecker auf einer „Setup“ Seite eingebaut. Mit ZEILE und SPALTE gibst du dann an, wo der Wecker angezeigt werden soll.

    Vielleicht ist für dich auch die etwas einfachere Version des Weckers von Interesse. Im Artikel „Wecker mit DOIF“ habe ich noch eine neue Variante erläutert.

  15. Holger Rudershausen

    Hallo Jurgen,
    Super Artickel.
    Ich habe bist auf ein paar Kleinigkeiten alles hinbekommen.
    1.define notAufstehen NOTIFY gr_Bewohner:awoken {Aufstehen($we)}
    2.define notWeckerStellen notify duWeckerTabUI:stellen {WeckerStellen()}
    Wo kommt denn der anschließende Code der Funktion hin?
    Viele Grüße , und danke für deine Bemühungen

  16. Die Funktionen werden alle in der Datei „99_myUtils.pm“ abgelegt. An die Datei gelangt man, wenn man in FHEM „Edit Files“ aufruft. Sollte sie noch nicht vorhanden sein, dann sollte es die Datei „myUtilsTemplate.pm“ geben. Diese editiert man dann und speichert sie unter dem Namen 99_myUtils.pm. Hierbei unbedingt darauf achten, dass der Code an der richtigen Stelle eingefügt – also am Ende der Datei das „1;“ stehen bleibt.

  17. Gibt es eine möglichkeit diese Seite lesen zu können?
    Es wäre schön, wenn die Kommentare unter dem Artikel stehen und nicht darübergeleft sind.
    MfG
    Elmar

  18. Sorry, war wieder ein fehlerhafter Codeschnipsel im Kommentar, der sie Seite zerschossen hat. Sollte nun behoben sein.

  19. Hi 🙂

    ich hätte gerne hinter jedem Tag ein On/Off switch. Wie könnte ich das in FHEM realisieren? TabletUI ist mir klar. Ich würde es in das Dummy reinschreiben. Aber wo füge ich die Abfrage in den Code ein?
    Danke 🙂

  20. Schau dir mal meine Umsetzung des Weckers mittels DoIF an. Damit würden deine Anforderungen vielleicht einfacher umgesetzt werden können.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Why ask?

x

Check Also

Tibber Erfahrungen nach drei Monaten

Seit Mitte April nutzen wir die dynamischen Strompreise von Tibber*. Nach dem ersten vollen Monat ...