Ich bekomme immer wieder Anfragen, wie bestimmte Szenarien oder Aktionen in FHEM realisiert werden können. Meistens ist es nicht ganz so einfach dies über die üblichen Komponenten von FHEM zu konfigurieren. Hier sind dann Programmierkenntnisse gefragt… aber keine Angst, so kompliziert ist dies nun auch nicht. Vieles kann über einfache IF-Abfragen realisiert werden, wie ihr in diesem kleinen FHEM Programmierkurs sehen könnt.
In meiner Datei 31_actions.cfg, die im Ordner /opt/fhem/mycfg liegt, habe ich unterschiedliche Aktionen definiert, wie z. B.
define Action_Media_Heimkino dummy
attr Action_Media_Heimkino alias Heimkino
attr Action_Media_Heimkino devStateIcon on:general_an@orange off:general_aus@505050
attr Action_Media_Heimkino genericDeviceType switch
attr Action_Media_Heimkino group Komfort
attr Action_Media_Heimkino room Aktionen
attr Action_Media_Heimkino setList on off
attr Action_Media_Heimkino webCmd :
Damit für diese Aktion, die als dummy angelegt wurde, eine Aktion ausgeführt wird, habe ich einen Notify für alle Geräte, die mit Action_ beginnen angelegt:
#########################################################################
## Notify für alle Actions
#########################################################################
define Action_notify notify (Action_.*) { dkRouteActions($NAME, $EVENT) }
attr Action_notify group Notifiers
attr Action_notify room System
Dieser Notify sorgt dafür, dass die Funktion dkRouteActions aufgerufen wird. An diese Funktion wird der Gerätename (z. B. Action_Media_Heimkino) und das Event (z. B. on) übergeben.
Für diese Funktion habe ich ein eigenes Modul (99_dkHandleActions.pm) zur besseren Übersichtlichkeit geschrieben. D. h. bei mir gibt es für jede übergeordnete Aufgabe ein Modul. Diese Datei liegt in dem Ordner /opt/fhem/FHEM.
Ein Modul folgt immer dem selben Muster, ihr könnt also dieses Beispiel für eure eigenen Module als Vorlage verwenden.
##############################################
## Stand: 23.08.2016
##############################################
# $Id$
package main;
use strict;
use warnings;
use POSIX;
use Time::Local;
sub dkHandleActions_Initialize($$) {
my ($hash) = @_;
}
#######################################
##
##
## ROUTES
##
##
#######################################
sub dkRouteActions($$) {
my ($device, $event) = @_;
my $action = "dkAct_" . $device;
my $coderef=__PACKAGE__->can($action);
if ($coderef) {
$coderef->($event);
}
}
#######################################
## ACTIONS
#######################################
sub dkAct_Action_Media_Heimkino($) {
my ($event) = @_;
fhem("set HUEGroup0 $event", 1);
if ($event eq "on") { fhem("set Harmony activity Fernsehen", 1); }
if ($event eq "off") { fhem("set Harmony off", 1); }
}
1;
Was macht dieses Modul?
Zunächst erfolgt die Initialisierung des Moduls und es werden einige Bibliotheken wie time::local geladen.
Anschließend kommt die von mir geschrieben Funktion dkRouteActions(). Diese Route-Funktion ist bei mir in fast jedem Module vorhanden, da sie es mir auf einfache Weise erlaubt, dynamisch die Funktionen für die jeweiligen Geräte zuzuweisen. Anhand des übergebenen Gerätenamens wird die auszuführende Funktion bestimmt. Heisst das Geräte Action_Media_Heimkino, so wird die Funktion dkAct_Action_Media_Heimkino() aufgerufen und das Event an diese Funktion übergeben (z. B. on).
Die Funktion dkAct_Action_Media_Heimkino() ließt dann das übergebene Event ($event) aus. Anschließend wird der Befehl an FHEM gegeben, das Gerät HUEGroup0 zu schalten. Je nach dem, ob das Event on oder off war, wird ein weiterer Befehl an FHEM gesendet, um die Aktivität Fernsehen bei meiner Harmony einzuschalten.
Abhängigkeiten von anderen Geräten abfragen
Wenn ihr den State eines anderen Gerätes berücksichtigen wollte, könnt ihr dies z. B. wie folgt machen:
if (Value("EG_Wohnzimmer_Sensor_Terrassentuer") ne "open") {
fhem("set EG_Wohnzimmer_Rollo off");
}
Wenn die Terrassentür nicht offen ist, dann soll das Rollo geschlossen werden.
Schreibt in den Kommentaren, welche Programmierfragen ihr habt, dann würde ich aus diesem Beitrag eine Serie für euch erstellen.