Quantcast
Channel: Mein FHEM – krannich

Meine FHEM Konfiguration – Schritt für Schritt

$
0
0

Pünktlich zum neuen Jahr möchte ich mit einer Serie starten, in der ich zeige, wie ich meine FHEM Konfiguration aussieht.
Es setzt etwas Programmierkenntnisse voraus.

In meinen anderen Beiträgen habe ich ja schon grob durchblicken lassen, wie mein FHEM konfiguriert ist. Meine Konfiguration soll als Inspiration dienen und nicht als heiliger Gral. Ich habe schon viele Ansätze gesehen, für meine Zwecke bin ich mit meiner Variante sehr glücklich. Wer Verbesserungsvorschläge hat, kann diese gerne in den Kommentaren posten. Man lernt ja bekanntlich nie aus.

Generell besteht meine Konfiguration aus 3 Teilen:
1. fhem.cfg mit grundlegenden Einstellungen
2. mycfg-Verzeichnis mit allen erforderlichen Konfigurationsdateien
3. Verschiedene Dateien (z. B. 99_dkHandleMotion.pm) im Verzeichnis FHEM

1. Die Datei fhem.cfg

attr global userattr Geschoss Geschoss_map Haus Haus_map cmdIcon devStateIcon devStateStyle fm_fav fm_groups fm_name fm_order fm_type fm_view fp_homeserver genericDeviceType:switch,outlet,light,blind,speaker,thermostat,ignore,lock,window,contact icon lightSceneParamsToSave lightSceneRestoreOnlyIfChanged:1,0 sortby structexclude webCmd widgetOverride
attr global autoload_undefined_devices 1
attr global backup_before_update 0
attr global holiday2we Bremen
attr global latitude xx.xxxxx
attr global logfile ./log/system/fhem-%Y-%m-%d.log
attr global longitude y.yyyyy
attr global modpath .
attr global motd none
attr global sendStatistics never
attr global statefile ./log/system/fhem.save
attr global uniqueID ./FHEM/FhemUtils/uniqueID
attr global updateInBackground 1
attr global verbose 3
include /opt/fhem/mycfg/00_config.cfg
#EOF

In dieser Datei werden generelle globate User-Attribute (userattr) definiert. In meinem Fall habe ich einige für Apple Homekit ergänzt (genericDeviceType)

Zudem werden hier Angaben zu Feiertagen (holiday2we) gemacht und Angaben zu Latitude und Longitude, die wiederum für Wetter-Plugins verwendet werden.
Am Ende wird die 00_config.cfg eingebunden, die sich im Ordner mycfg befindet und als Steuerungsdatei für die Konfiguration dient.

2. Das Verzeichnis mycfg

Hier befinden sich verschiedene Dateien in denen die einzelnen Geräte und Plugins definiert und konfiguriert werden.

Folgende Dateien liegen in diesem Verzeichnis:

00_config.cfg
01_system.cfg
02_web.cfg
10_datastorage.cfg
20_EG_buero.cfg
[...]
28_structure.cfg
29_residents.cfg
30_remotes.cfg
31_actions.cfg
80_calendars.cfg
80_fritzbox.cfg
80_text2speech.cfg
[...]
90_timer.cfg
91_logs.cfg
91_plots.cfg
99_tests.cfg

Ich habe versucht die einzelnen Dateien etwas zu sortieren. Die Nummerierung entspricht der Reihenfolge wie sie in 00_config.cfg eingebunden sind. Sie dient lediglich der Übersicht in der Dateistruktur.
Die Reihenfolge ist bei mir:

00-09: Alles was zum System gehört (CUL, Web-Views, etc.)
10: Datastorage (in diesen Variabeln werden Messwerte bzw. Daten gespeichert)
20: Definition der Geräte in den einzelnen Räumen
21: Aussenbereich
28: Definition der Struktur des Hauses (EG, OG, Garten, Haus)
29: Definition der Bewohner zur Steuerung der Anwesenheit
30: Fernbedienungen
31: Aktionen im Web-View
80: Plugins (z. B. Fritzbox, Geofencing, Pushover, Text2Speech, etc.)
90: Timer
91: Logs und Plots
99: Test / Spielwiese

00_config.cfg (ein kurzer Auszug)

Hier ein kurzer Auszug wie die 00_config.cfg bei mir aussieht.
Es werden die einzelnen Konfigurationsdateien per Include geladen.

Ihr solltet ggf. darauf achten, dass eine logische Reihenfolge eingehalten wird. Also CUL definieren bevor dieser in weiteren Definitionen verwendet wird.

define TABLETUI HTTPSRV dk /opt/fhem/www/tablet/ Tablet-UI
include /opt/fhem/mycfg/01_system.cfg
include /opt/fhem/mycfg/02_web.cfg
include /opt/fhem/mycfg/10_datastorage.cfg
[...]

Die Dateien im Ordner FHEM

Die eigentliche Haussteuerung bzw. die Logik dahinter geschieht (größtenteils) in den einzelnen Dateien im FHEM-Ordner.

Folgende Dateien liegen in diesem Verzeichnis:

99_dkHandleActions.pm
99_dkhandleCalendars.pm
99_dkHandleFritzbox.pm
99_dkHandleHeating.pm
[...]
99_dkUtils.pm
99_dkTTS.pm

Für jeden Bereich habe ich eine eigene Steuerungsdatei erstellt. So kann ich immer den Überblick behalten und die Dateien werden nicht all zu lang und komplex. Von Nachteil ist, dass die Gerätenamen nur schwer geändert werden können, da diese in mehreren Dateien verwendet werden. Ein vernünftiges IDE mit dem man in mehreren Dateien suchen kann hilft hier ungemein. Zudem sollte man sich im Vorfeld Gedanken machen, wie man seine Variabeln und Gerätenamen nennen will. Der Clean-Code-Ansatz hilft hier ganz gut weiter.


Meine FHEM Konfiguration – Fritzbox

$
0
0

Beispiel Fritzbox

Nachfolgend ein Beispiel wie die Steuerung der Fritzbox bei mir in FHEM aussieht:

80_fritzbox.cfg

#########################################################################
##
##  80_FRITZBOX
##
##  Stand.........: 22.12.2014
##  Zweck.........: Überwacht eingehende Anrufe auf der FritzBox
##  Besonderheiten: Sprachausgabe über RaspberryPi,
##		    Anzeige im Fernseher über Enigma2-Receiver
##                  
#########################################################################
##
## Init
##
#########################################################################

define fritzbox FB_CALLMONITOR x.x.x.x
attr fritzbox alias FritzBox
attr fritzbox group PlugIns
attr fritzbox reverse-search phonebook
attr fritzbox reverse-search-phonebook-file ./FRITZ.Box_Telefonbuch.xml
attr fritzbox room System


#########################################################################
##
## Notifications
##
#########################################################################

define fritzbox_notify notify fritzbox:event:.* { dkRouteFritzBox() }
attr fritzbox_notify group Notifiers
attr fritzbox_notify room System


#########################################################################
## EOF

Was macht diese Datei?
Zunächst wird das Plugin FB_CALLMONITOR initialisiert (IP Eurer Box bitte anpassen)
Es wird ein Telefonbuch geladen FRITZ.Box_Telefonbuch.xml, das man einfach aus der Fritzbox exportieren kann (bitte entsprechend umbenennen).
Anschließend wir ein NOTIFY definiert, der bei allen events (event:.*) die Funktion dkRouteFritzbox() aufruft. Da man die Events direkt bei der Fritzbox auslesen kann, ist eine Übergabe des events als Parameter nicht erforderlich. Normalerweise wäre der Aufruf dkRouteFunktionsname($NAME, $EVENT), um Gerätename und Event zu übergeben.

99_dkHandleFritzbox.pm

##############################################
## Stand: 28.07.2015 - V0001
##############################################
# $Id$
package main;

use strict;
use warnings;
use POSIX;
use Time::Local;

sub dkHandleFritzbox_Initialize($$) {
 	my ($hash) = @_;
}

#######################################
##
##
## ROUTES
##
##
#######################################

sub dkRouteFritzBox() {
	my $event = ReadingsVal("fritzbox", "event", "none");
	if ($event eq "ring") { dkPhoneRing(); }
	if ($event eq "connect") { dkPhoneConnect(); }
	if ($event eq "disconnect") { dkPhoneDisconnect(); }
	if ($event eq "call") { dkPhoneCall(); }
}

#######################################
##
##
## ACTIONS
##
##
#######################################

sub dkPhoneCall() {
	
}

sub dkPhoneRing() {
	my $number = ReadingsVal("fritzbox", "external_number", "unknown");
	my $telname = ReadingsVal("fritzbox", "external_name", "unknown");

	if (Value("rr_Dennis") ne "home") {
		if ($telname eq "unknown") {
			dkPush("call", "Ein Anruf von $number");
		} else {
			dkPush("call", "Ein Anruf von $telname");
		}
	}
	
	if ($telname eq "unknown") {
		dkTalk("Ein Anruf von $number");
		dkDisplayText("Anruf von $number");
	} else {
		dkTalk("$telname ruft an");
		dkDisplayText("Anruf von $telname");
	}
}


sub dkPhoneConnect() {
	my $internal_number = ReadingsVal("fritzbox", "internal_number", "unknown");
	dkStoreAVRVolume();
	dkSetAVRVolume('32');
}


sub dkPhoneDisconnect() {
	dkRestoreAVRVolume();
}

1;

Was macht diese Datei?
Die Hauptfunktion ist in diesem Script ist dkRouteFritzBox(). Hier werden abhängig vom aufgetretenen Event die weiteren Methoden aufgerufen.

In meinem Fall wird bei einem eingehenden Anruf überprüft, ob ich zuhause bin. Ist dies nicht der Fall erhalte ich eine Push-Nachricht mit der Telefonnummer bzw. dem Anrufernamen. Zudem erfolgt eine Sprachausgabe (dkTalk) sowie die Anzeige im Fernseher (dkDisplayText). Diese Methoden überprüfen intern, ob die jeweiligen Geräte angeschaltet sind und sorgen dann für eine Ausgabe.

Wird der Anruf angenommen bzw. kommt eine Verbindung zu Stande (dkPhoneConnect()) so wird der aktuelle Lautstärke-Wert des AV-Receivers gespeichert und die Lautstärke reduziert.

Wird wieder aufgelegt (dkPhoneDisconnect) wird die Lautstärke am AV-Receiver wieder auf den zuvor gespeicherten Wert zurückgesetzt.

Meine FHEM Konfiguration – dkUtils DAS Helferlein

$
0
0

FHEM ist sehr komplex und häufig wiederholen sich die teilweise sehr langen Befehlsketten. Aus diesem Grund habe ich verschiedene Funktionen geschrieben, dir mir die Programmierung erleichtern (dkUtils.pm). So ist mein Helferlein dkUtils entstanden.

Im Folgenden möchte ich euch diese Funktionen vorstellen. Wenn ihr die einzelnen Code-Fragmente in eine Datei kopiert, habt ihr meine dkUtils.

Über konstruktive Verbesserungen in den Kommentaren bin ich dankbar.

dkUtils.pm: Genrelles

##############################################
## Stand: 13.02.2016
##############################################
# $Id$
package main;

use strict;
use warnings;
use POSIX;
use Time::Local;


sub dkUtils_Initialize($$) {
 	my ($hash) = @_;
}

So wird jedes eigene Modul (dkUtils) initialisiert und einige Abhängigkeiten wie z. B: zu Time::Local hergestellt.

dkUtils.pm: Allgemeine Funktionen

#######################################
##
##
## ALLGEMEINE FUNKTIONEN
##
##
#######################################

sub dkOn($) {
	my($device) = @_;
	fhem("set $device on");
}


sub dkOff($) {
	my($device) = @_;
	fhem("set $device off");
}


sub dkToggle($) {
	my ($device) = @_;
	fhem("set $device toggle");
}

Diese Funktionen schalten Geräte ein oder aus, bzw. ändern deren Zustand abhängig davon ob sie gerade ein- oder ausgeschaltet sind.

sub dkAutoOff($$$) {
	my ($device, $event, $durationInHours) = @_;
	my ($deviceAutoOff) = $device . "_AutoOff";	
	if (dkExists($deviceAutoOff)) { fhem ("delete $deviceAutoOff"); }
	if ($event eq "on") {
		my $mytime = dkTimeAddHoursHMS($durationInHours);
		fhem ("define $deviceAutoOff at $mytime { fhem('set $device off') }");
	}
}

Die Funktion dkAutoOff sorgt dafür, dass ein Gerät nach einer gewissen Zeit in Stunden (0.5 für eine halbe Stunde geht auch) ausgeschaltet wird. Dies könnte man auch über „on-till“ oder „on-for-timer“ jedoch lösen diese Timer im Falle eines Neustarts nicht aus.
Achtung: Diese Funktion hat weitere Abhängigkeiten. Zum einen dkExists() (prüft ob Gerät vorhanden) und dkTimeAddHoursHMS() (addiert zur aktuellen Zeit x Stunden).
Eine ausführliche Beschreibung findet ihr in dem Beitrag AutoOff für Geräte erstellen.

dkUtils.pm: Zustände, Gerätenamen und Parameter

#######################################
##
##
## Device States, Alias und Parameter
##
##
#######################################

sub dkGetReading($$){
	my($device, $reading) = @_;
	return ReadingsVal($device, $reading, "unknown");
}


sub dkGetState($){
	my($device) = @_;
	return ReadingsVal($device, "state", "unknown");
}


sub dkGetStateLastChange($) {
	my($device) = @_;	
	return ReadingsTimestamp($device,"state","0");
}


sub dkGetAttr($$) {
	my($device, $attr) = @_;	
	return AttrVal($device, $attr, "unknown");
}


sub dkGetAlias($) {
	my($device) = @_;	
	return AttrVal($device, "alias", "unknown");
}


sub dkSetValue($$) {
	my($device, $value) = @_;
	fhem("set $device $value");
}


sub dkSetReading($$$) {
	my($device, $reading, $value) = @_;
	fhem("setreading $device $reading $value");
}

#######################################

sub dkExists($) {
	my ($object) = @_;
	if ( Value($object) ) {	return 1; } else { return 0; }
}


sub dkValueExists($) {
	my ($object) = @_;
	if ( Value($object) eq "???" || ReadingsVal($object, "state", "???") eq "???" ) {
		return 0;
	} else {
		return 1;
	}
}

Mit den obigen Funktionen kann ich relativ einfach einen Gerätenamen (Alias) sowie Werte und Zustände von Geräten abfragen und setzen. Darüber hinaus kann überprüft werden, ob ein Gerät bzw. ein Value existiert.

dkUtils.pm: Watchdog

#######################################
##
##
## Watchdog
##
##
#######################################

sub dkWatchdog($$$) {
	my ($device, $state, $durationInHours) = @_;
	my $device_state = dkGetState($device);
	my $device_alias = dkGetAlias($device);
	
	dkRemoveWatchdog($device);
	if ($device_state eq $state) {
		dkAddWatchdog($device,$state,$durationInHours);
		dkPush("device", "$device_alias ist noch angeschaltet.");
	} 
}


sub dkAddWatchdog($$$) {
	my($device, $state, $durationInHours) = @_;
	my $device_notify = $device . "_dkWatchdog";
	my $mytime = dkTimeAddHoursHMS($durationInHours);
	fhem("define $device_notify at $mytime { dkWatchdog('$device', '$state', $durationInHours) }");
}


sub dkRemoveWatchdog($) {
	my($device) = @_;
	my $device_notify = $device . "_dkWatchdog";
	if (dkExists($device_notify)) {
		fhem ("delete $device_notify");
	}
}

Mein dkWatchdog sorgt dafür, dass nach einer bestimmten Zeit überprüft wird, ob ein Gerät noch angeschaltet ist. Schalte ich z. B. eine Pumpe an, so wird der Watchdog gesetzt (dkAddWatchdog), schalte ich sie aus, wird der Watchdog wieder gelöscht (dkRemoveWatchdog). Nach dem Anschalten wird z. B. nach einer Stunde überprüft (dkWatchdog), ob das Gerät noch an ist und entsprechend eine Push-Notification verschickt. So kann sichergestellt werden, dass man nie vergisst Geräte wieder auszuschalten.

dkUtils.pm: Zeit-Funktionen

#######################################
##
##
## Zeit-Funktionen
##
##
#######################################

sub dkCurrentHour($$) {
	my ($operator,$hour) = @_;
	my $currenthour = strftime("%H", localtime)+0; # +0 = hack to format as integer
	my $command = "$currenthour $operator $hour";
	if (eval($command)) {
		return 1;
	} else {
		return 0;
	}
}


sub dkTimeFormat($){
	my $Sekundenzahl = @_;
	return sprintf("%02d:%02d:%02d", ($Sekundenzahl/60/60)%24, ($Sekundenzahl/60)%60, ($Sekundenzahl)%60 );
}


sub dkTimeAgeInHours($$) {
	my ($now, $timestamp) = @_;
	my @splitdatetime = split(/ /,$timestamp);
	my @splitdate = split(/-/, $splitdatetime[0]);
	my @splittime = split(/:/, $splitdatetime[1]);
	my $last_state_time =  timelocal($splittime[2], $splittime[1], $splittime[0], $splitdate[2], $splitdate[1]-1, $splitdate[0]);
	my $age_in_hours = ($now - $last_state_time) / 3600;		
	return $age_in_hours;
}

sub dkTimeHoursToHMS($) {
	my ($hours) = @_;
	$hours = $hours * 60 * 60;
	return strftime("\%H:\%M:\%S", gmtime($hours) );
}

sub dkTimeAddHoursHMS($) {
	my ($hours) = @_;
	$hours = $hours * 60 * 60;
	return strftime("\%H:\%M:\%S", localtime(time + $hours) );
}

Diese Funktionen konvertieren oder berechnen Timestamps oder HMS-Zeitangaben (also Stunde:Minute:Sekunde).
Die Funktion dkTimeAgeInHours kann z. B. dafür verwendet werden, um herauszufinden, ob sich ein Wert innerhalb einer bestimmten Zeit verändert hat.

dkUtils.pm: Sprachausgabe

#######################################
##
##
## Sprachausgabe
##
##
#######################################

sub dkTalk($) {
	my ($message) = @_;
	if (!$message) { return; }
	$message =~ s/_/ /g;
	$message =~ s/-/ /g;
	fhem("set mytts tts $message");
}


dkTalk ermöglicht die Sprachausgabe. Bevor die Nachricht an das Gerät übermittelt wird, werden "_" und "-" entfernt, damit eine unterbrechungsfreie Ausgabe erfolgt und diese Zeichen nicht gesprochen werden.


<h2>dkUtils.pm: Push-Nachrichten</h2>


#######################################
##
##
## Push Mitteilungen
##
##
#######################################

sub dkPush($$) {
	my ($type, $message) = @_;
	if (!$message) { return; }
	if ($type eq "default") 	{ fhem("set pushover msg '$message'"); }
	if ($type eq "warning") 	{ fhem("set pushover msg 'FHEM Warning' '$message' '' 0 'gamelan' "); }
	if ($type eq "call") 		{ fhem("set pushover msg 'FHEM' '$message' '' 0 'bike' "); }
	if ($type eq "device") 		{ fhem("set pushover msg 'FHEM' '$message' '' 0 'bike' "); }
	if ($type eq "attention") 	{ fhem("set pushover msg 'FHEM' '$message' '' 0 'bugle' "); }
	if ($type eq "magic") 		{ fhem("set pushover msg 'FHEM' '$message' '' 0 'magic' "); }
}

Mit dkPush können Push-Nachrichten angestoßen werden. Je nach gesetzten Type ertönt in der App ein anderer Signalton.

dkUtils.pm: Textausgabe auf Fernseher

#######################################
##
##
## Textausgabe auf Fernseher
##
##
#######################################

sub dkDisplayText($) {
	my ($message) = @_;
	if (!$message) { return; }
	if ( ReadingsVal("SatReceiver", "presence", "unknown") eq "present") {
		fhem("set SatReceiver msg info 10 $message");
	}
}

Diese Funktion sorgt dafür, dass auf meinem Enigma2-Sat-Receiver ein Mitteilung erscheint (z. B. wenn eine Anruf eingeht).

dkUtils.pm: FHEM-Start/Stop

#######################################
##
##
## FHEM ROUTINES
##
##
#######################################

sub dkFHEM($) {
	my ($event) = @_;
	
	if ($event eq "INITIALIZED") {
		dkSetDefaults();
		fhem("set SCC led 00");
		dkTalk("System gestartet.");
	}
	
	if ($event eq "SHUTDOWN") {
		dkTalk("System fährt runter.");
	}
	
}

Je nach Status von FHEM (Initialized oder Shutdown) erfolgt eine kurze Sprachausgabe.

dkUtils.pm: Helpers

#######################################
##
##
## HELPERS
##
##
#######################################

sub _isWeekend() {
	my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime;
	# Samstag = 0, Sonntag = 6
	if($wday == 0 || $wday == 6) {
		return 1;
	} else {
		return 0;
	}
}

#######################################

1;

Diese interne Funktion gibt zurück, ob es Wochenende ist oder nicht.

Bitte nicht vergessen am Ende der Datei ein "1;" einzufügen (siehe letzte Zeile Helpers)

Fazit

Sicherlich könnten die Funktionen in dkUtils an der ein oder anderen Stelle noch optimiert werden, aber sie helfen mir Schreibarbeit zu reduzieren und sorgen dafür, dass der eigene Code lesbarer wird und aufgeräumter wird.

Meine FHEM Konfiguration – Geräte an- und ausschalten für Fortgeschrittene

$
0
0

In diesem Beitrag möchte ich etwas tiefer in die Programmierung einsteigen und zeigen wie man Geräte „sinnvoll“ an- und ausschalten kann.

Das Thema mag auf den ersten Blick trivial klingen, doch es sorgt dafür, dass der Funkverkehr reduziert wird und die Geräte auch nur dann geschaltet werden, wenn es auch wirklich erforderlich ist.

Die Funktionen dkOn() und dkOff() kennt ihr ja schon aus dem vorherigen Beitrag.
Für die „neue“ Funktion habe ich sie etwas modifiziert. Die beiden Funktionen rufen nun wiederum eine Funktion namens dkSetDevice() auf. Es werden zwei Parameter übergeben: device(s) ($input) und state ($value).

Der $input kann ein komma-separierter String sein, so dass mehrere Geräte an- bzw. ausgeschaltet werden können.

Anschließend wird überprüft, ob das jeweilige Gerät existiert.

Existiert das Gerät gibt es zwei Fälle:
(a) es handelt es sich um ein Homematic-Gerät dessen Status nicht „unknown“ oder der gewünschte Zustand ist
(b) es handelt sich um kein Homematic-Gerät

Bei letzterem wird der Status nicht überprüft, da es insb. bei Intertechno-Geräten vorkommen kann, dass nicht geschaltet wird.

Die dann bereinigte Liste wird entsprechend geschaltet.

Und hier der Code:


sub dkSetDevice($$) {
	my ($input, $value) = @_;	
	my @devices = split(',', $input);
	my @validated_devices;

	foreach my $device (@devices) {
		if (dkExists($device)) {

			if (dkIsHomematic($device)) {
	
				my $state = dkGetState($device);
				if ($state ne $value && $state ne "unknown") {
					push(@validated_devices, $device);
				}
				
			} else {
	
				push(@validated_devices, $device);
				
			}
			
		}
	}

	my $cleaned_device_list = join(",", @validated_devices);
	if ($cleaned_device_list ne "") {
		fhem("set $cleaned_device_list $value", 1);
	}
		
}


sub dkOn($) {
	my($device) = @_;
	dkSetDevice($device, "on");
}


sub dkOff($) {
	my($device) = @_;
	dkSetDevice($device, "off");
}

Hier die benötigten Funktionen aus der dkUtils.pm

sub dkIsHomematic($) {
	my ($device) = @_;	
	my $device_type = dkGetAttr($device, "model");
	if (substr($device_type, 0, 2) eq "HM") {
		return 1;
	} else {
		return 0;
	}
}

sub dkExists($) {
	my ($object) = @_;
	if ( Value($object) ) {	return 1; } else { return 0; }
}

Meine FHEM Konfiguration – notify mal anders

$
0
0

Um die Anzahl an Notify-Definitionen in FHEM zu reduzieren habe ich etwas experimentiert, so dass die Logik nicht mehr direkt über eine Notify erfolgt, sondern direkt in der Programmierung in Perl. Für meine Anwendungsfälle ist dies vollkommen ausreichend.

Hier ein Beispiel aus meiner 31_actions.cfg:

#########################################################################
## 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, dann alle Events an die Funktion dkRouteActions geleitet werden.

Die korrespondierende PERL-Datei lautet 99_dkHandleActions.pm
Hier prüft die Funktion dkRouteActions zunächst, ob die Funktion dkAct_AKTIONSNAME vorhanden ist.

Beispiel: heißt das Gerät „Action_Panic“, so muss analog eine Funktion namens „dkAct_Action_Panic“ definiert sein.


#######################################
##
##
## ROUTES
##
##
#######################################

sub dkRouteActions($$) {
	my ($device, $event) = @_;
	my $action = "dkAct_" . $device;
	my $coderef=__PACKAGE__->can($action);
	if ($coderef) { 
		$coderef->($event);
	}
}

Aus diese Weise könnt ihr nicht nur die Notify-Definitionen reduzieren, sondern auch die Logik komplett in PERL ausgliedern. Darüber hinaus müsst ihr nicht für jedes neue Gerät einen Notify anlegen, sondern könnt gleich in PERL die Funktion implementieren.

Lasst mich wissen, wie Ihr eure Programmierung optimiert und Overhead reduziert.