99 myUtils anlegen: Unterschied zwischen den Versionen

Aus FHEMWiki
(Die Seite wurde neu angelegt: „Mit wachsender Anzahl von eigenen Helfer-Programmen wird die Speicherung von perl-code in notify unübersichtlich. Es besteht die Möglichkeit, eine eigene Pro…“)
 
Zeile 96: Zeile 96:


== Links ==
== Links ==
* <nowiki>[http://notepad-plus-plus.org/ Notepad++]</nowiki> Editor
* [http://notepad-plus-plus.org/ Notepad++] Editor
 
[[Kategorie:Code Snippets]]

Version vom 12. Mai 2013, 00:04 Uhr

Mit wachsender Anzahl von eigenen Helfer-Programmen wird die Speicherung von perl-code in notify unübersichtlich. Es besteht die Möglichkeit, eine eigene Programmdatei zu erzeugen, in der mehrere kleine Programme gesammelt und dann aus diversen notify- oder at-Anweisungen aufgerufen werden.

Eine neue Programmdatei erzeugen

Eine ‚leere‘ Programmdatei sieht folgendermassen aus:

package main;
use strict;
use warnings;
use POSIX;
sub
myUtils_Initialize($$)
{
 my ($hash) = @_;
}
1;

Legen Sie in Ihrem fhem-Programmverzeichnis (FHEM) eine Datei mit dem Name 99_myUtils.pm an und kopieren Sie den o.g. Inhalt hinein.

Eine einfache Möglichkeit: Wählen Sie in fhem den Menüpunkt 'Edit Files', klicken Sie die Datei '99_Utils.pm' an. Im oberen Bereich gibt es einen button 'Save as' - tragen Sie in dem Textfeld 99_myUtils.pm ein und klicken dann auf den Save as-button. Danach erscheint Ihre Programmdatei ebenfalls unter dem Menüpunkt 'Edit Files'. Ersetzen Sie dann den Inhalt mit dem Programmcode von oben - oder löschen Sie alle Routinen heraus, so dass der code wie oben übrig bleibt :)

Für etwas längere Programme ist ein externer Editor empfohlen, der Sie dabei unterstützt, z.B. Klammernpaare korrekt zu setzen - dies ist der häufigste Fehler! Dabei unterstützt z.B. das kostenlose Notepad++.

Drei Dinge sind für Ihre Programmdatei besonders zu beachten:

  1. Der Dateiname muss mit 99_ beginnen. Fhem lädt beim Start alle Programmdateien mit dem prefix 99_. Andere Programmdateien werden erst dann geladen, wenn sie durch eine define-Anweisung in fhem.cfg angefordert werden. So wird z.B. 10_FS20.pm erst geladen, wenn beim Einlesen der Datei fhem.cfg das erste define für ein FS20-device abgearbeitet wird. Da Ihre eigene Programmsammlung wahrscheinlich kein neues Gerät mit einem zugehörigen define-Befehl implementiert, würde sie also nie geladen, wenn ihr Name nicht mit 99_ beginnt.
  2. Damit die neue Datei bei "Edit Files" angezeigt wird, muss sie mit Utils.pm enden. Also zum Beispiel 99_meineUtils.pm
  3. Der Name der Programmdatei muss mit dem Namen der Initialize-Routine übereinstimmen. Wenn Sie Ihr Programm also 99_Werkzeugkasten.pm nennen, muss die im code dargestellte initialize-Routine sub Werkzeugkasten_Initialize heißen.
  4. Die Zeile 1; muss immer die letzte Programmzeile sein. Wenn Sie also eigene Routinen in Ihre Programmsammlung einfügen, tragen Sie diese zwischen dem Ende der Initialize-Routine und der abschließenden Zeile 1; ein.

Eigene Routinen einfügen

Als Beispiel dient das Umsetzen von FS20 toggle-Events aus diesem Wiki-Eintrag. Das gesamte Programm sieht dann folgendermaßen aus:

package main;
use strict;
use warnings;
use POSIX;
sub
myUtils_Initialize($$)
{
 my ($hash) = @_;
}
##########################################################
# Untoggle
# toggle-Vorgänge in den Status on/off umsetzen
sub Untoggle($) {
 my ($obj) = @_;
 if (Value($obj) eq "toggle"){
  if (OldValue($obj) eq "off") {
   {fhem ("setstate ".$obj." on")}
  }
  else {
   {fhem ("setstate ".$obj." off")}
  }
 }
 else {
  {fhem "setstate ".$obj." ".Value($obj)}
 } 
}
1;

Der Aufruf erfolgt dann z.B. so:

#fhem.cfg
define lampe_untoggle notify lampe {Untoggle(„@“)}

Der Aufruf aus einem notify (oder at) erfolgt als Perl-code, muss also in geschweiften Klammern stehen. Der Aufruf erfolgt durch Angabe des Namens der Routine (Untoggle) unter Angabe der zu übergebenden Parameter (hier "@"). Im Programm wurde die Routine Untoggle mit einem Parameter definiert ( Untoggle($) , die Anzahl der $-Zeichen macht's). Der Wert des übergebenen Parameters wird in der ersten Programmzeile in die Variable $obj übernommen (my ($obj) = @_; ). Der Aufruf erfolgt mit Untoggle(„@“) . Der Platzhalter @ in fhem steht für den Namen des Geräts. Im o.g. Beispiel erfolgt Aufruf also eigentlich mit Untoggle(„lampe“). Natürlich können Sie beim Aufruf auch feste Werte ( „lampe1“ ) oder Variablen ( $hour ) übergeben.

Routinen mit mehreren Parametern

In der Definition der Routine geben Sie ausserdem an, wieviele Parameter übergeben werden sollen, für 2 Parameter z.B. so:

define test at *09:00 { wakeup($we, „Schlafzimmerlampe“) }

Die Deklaration der Routine in Ihrer Programmdatei muss dann so beginnen:

#Nur am Wochenende eingeschaltet
sub wakeup($$) {
my ($wochenende, $device) = @_;
if ($wochenende) {
   fhem("set $device on");
  } else {
   fhem("set $device off");
 }
}

Durch die Anzahl der $-Zeichen in der Routinen-Deklaration wird also die Anzahl der Parameter festgelegt. In der ersten Programmzeile Ihrer Routine übernehmen Sie dann die übergebenen Parameterwerte in lokale Variablen. Wie beim Routinen-Aufruf muss auch hierbei die Anzahl der Parameter mit der Routinen-Deklaration (also Anzahl der $-Zeichen) übereinstimmen.

Routinen ohne Parameter

Auch Routinen ohne Parameter sind natürlich möglich. Definition und Aufruf sehen dann folgendermassen aus:

sub parameterlos() {....
 { parameterlos() }

Eigene Programmdatei laden

Ihre Programmdatei wird nur bei fhem-start geladen - es sei denn Sie verwenden das Kommando reload. Also bearbeiten Sie Ihr Programm, speichern die Programmdatei, und weisen fhem dann an, die Programmdatei erneut zu laden. Der Befehl dazu, der in das fhem Kommandofeld eingegeben wird, lautet:

reload 99_myUtils.pm

Treten beim Laden (Syntax)fehler auf, werden diese am Bildschirm wie auch im Log angezeigt. Da der Ladevorgang fehlgeschlagen ist, stehen Ihre eigenen Routinen nun nicht zur Verfügung (bzw in der zuletzt erfolgreich geladenen Version). Beheben Sie also alle Fehler, speichern Sie Ihre Programmdatei erneut und führen Sie wieder ein reload aus.

Viel Erfolg!

Links