<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>http://wiki.fhem.de/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=ChristophMorrison</id>
	<title>FHEMWiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.fhem.de/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=ChristophMorrison"/>
	<link rel="alternate" type="text/html" href="http://wiki.fhem.de/wiki/Spezial:Beitr%C3%A4ge/ChristophMorrison"/>
	<updated>2026-04-11T02:17:51Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Volkszaehler&amp;diff=36180</id>
		<title>Volkszaehler</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Volkszaehler&amp;diff=36180"/>
		<updated>2021-11-05T18:47:51Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* Daten mit Volkszaehler loggen */ Hinweis darauf, dass 23_VOLKSZAEHLER geladen sein muss, da sonst LWP::UserAgent::get nicht verfügbar ist (Forum #123917)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Einbindung der Daten von voelkszaehler.org in FHEM&lt;br /&gt;
|ModType=x&lt;br /&gt;
|ModCmdRef=VOLKSZAEHLER &lt;br /&gt;
|ModForumArea=&lt;br /&gt;
|ModFTopic=http://forum.fhem.de/index.php/topic,12834.0.html&lt;br /&gt;
|ModTechName=23_VOLKSZAEHLER.pm&lt;br /&gt;
|ModOwner=({{Link2FU|81|Forum}}/[[Benutzer Diskussion:Bgewehr|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
[[Datei:volkszaehler.png|right]]&lt;br /&gt;
&lt;br /&gt;
Volkszaehler.org ist ein freies SmartMeter Projekt für den Selbstbau ([http://www.volkszaehler.org siehe volkszaehler.org]) Der Nutzer behält dabei die vollständige Kontrolle über die anfallenden Daten seiner Strom-, Wasser- und Gaszähler.&lt;br /&gt;
&lt;br /&gt;
==Features==&lt;br /&gt;
* 100% Open-Source&lt;br /&gt;
* kostenlos&lt;br /&gt;
* offene Protokolle&lt;br /&gt;
* erweiterbar&lt;br /&gt;
* minmale Anforderungen (LAMP-Stack)&lt;br /&gt;
* flexibele Verwaltungsmöglichkeiten&lt;br /&gt;
* Verbrauchs &amp;amp; Kostenprognose&lt;br /&gt;
* verschiedenste Messgrößen&lt;br /&gt;
** Strom&lt;br /&gt;
** Wasser&lt;br /&gt;
** Gas&lt;br /&gt;
** Betriebsstunden&lt;br /&gt;
** Temperatur&lt;br /&gt;
* Läuft u. a. auf Raspberry Pi ([http://wiki.volkszaehler.org/howto/raspberry_pi_image Installationsbeschreibung)]&lt;br /&gt;
&lt;br /&gt;
== Volkszaehler in FHEM einbinden ==&lt;br /&gt;
&lt;br /&gt;
Das FHEM-Modul für Volkszaehler.org bindet diese Daten in FHEM ein. Das Modul 23_VOLKSZAEHLER.pm greift per http auf den Volkszaehler zu und interpretiert die JSON-Antwort in FHEM-device-Readings. Daraus können Logs und Plots gebildet werden oder devices mit Kennzahlen aus den Volkszaehler-Daten. &lt;br /&gt;
&lt;br /&gt;
Es ist z. B. für Solarstrom-Anlagenbesitzer denkbar, bei hoher verfügbarer Sonnenenergie mit FHEM Verbraucher einzuschalten, um die Eigenverbrauchsrate zu erhöhen, was die Energiekosten reduziert.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Für die Installation müssen einige Files heruntergeladen und in die richtigen Verzeichnisse kopiert werden.&lt;br /&gt;
&lt;br /&gt;
=== FHEM-Modul ===&lt;br /&gt;
&lt;br /&gt;
Meine aktuellen Versionen liegen hier: &amp;lt;code&amp;gt;https://github.com/bgewehr/fhem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Datei &amp;lt;code&amp;gt;23_VOLKSZAEHLER.pm&amp;lt;/code&amp;gt; kommt ins Verzeichnis &amp;lt;code&amp;gt;../fhem/FHEM&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Datei &amp;lt;code&amp;gt;volkszaehler.gplot&amp;lt;/code&amp;gt; kommt ins Verzeichnis &amp;lt;code&amp;gt;../fhem/www/gplot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nur zur Sicherheit: Um die Dateien auf einem Windows-Rechner lokal zu erstellen, bitte den Text aus der &amp;quot;raw&amp;quot; Ansicht aus Github kopieren und bitte nicht in Notepad, sondern in z. B. [http://www.heise.de/download/notepad.html Notepad++] einfügen und dann unter dem richtigen Dateinamen speichern. Mit Notepad von Microsoft werden falsche Zeilenenden erzeugt, die dann unter Linux nicht funktionieren.&lt;br /&gt;
&lt;br /&gt;
=== JSON für Perl ===&lt;br /&gt;
Das Modul nutzt einen JSON-Interpreter, um die Antwort vom Volkszaehler in eine PERL-Variable zu wandeln. Dazu ist ein zusätzliches PERL Modul notwendig.&lt;br /&gt;
&lt;br /&gt;
#&amp;gt; cpan JSON&lt;br /&gt;
&lt;br /&gt;
sollte alle nötigen Dateien installieren. &lt;br /&gt;
&lt;br /&gt;
Hinweis zur Fritz!Box:&lt;br /&gt;
Da die Fritz!Box inzwischen nicht mehr für FHEM taugt, habe ich die für diese Installation nötigen beonderen JSON files hier nicht mehr aufgelistet. Auch die aktuelle Version meines Moduls greift auf das aktuelle JSON Perl Modul zurück und wird so auf einer Fritz!Box nicht mehr laufen.&lt;br /&gt;
&lt;br /&gt;
== Definition der devices ==&lt;br /&gt;
Die Device-Definitionen werden in einer [[Konfiguration]] (üblicherweise fhem.cfg) angelegt&lt;br /&gt;
:&amp;lt;code&amp;gt;define &amp;lt;name&amp;gt; VOLKSZAEHLER &amp;lt;ip-address&amp;gt; &amp;lt;port-nr&amp;gt; &amp;lt;channel&amp;gt; &amp;lt;state:last/min/max/average/consumption&amp;gt; &amp;lt;poll-delay&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;name&amp;gt;: Name des neuen FHEM-devices&lt;br /&gt;
* &amp;lt;ip-address&amp;gt;: IP des Volkszaehlers&lt;br /&gt;
* &amp;lt;port-Nr&amp;gt;: Port, auf dem der Volkszaehler-http-Server erreichtbar ist&lt;br /&gt;
* &amp;lt;channel&amp;gt;: UUID des Volkszaehler-Frontend-Channels, der gelesen werden soll&lt;br /&gt;
* &amp;lt;state&amp;gt;: Das Reading, welches als state genommen werden soll, kann im define gewählt werden. Dabei besteht die Auswahl aus&lt;br /&gt;
** last (letzter geladener Wert, manchmal leer bei zu kleinem poll-delay)&lt;br /&gt;
** min (kleinster Wert innerhalb des poll-delay, manchmal leer bei zu kleinem poll-delay)&lt;br /&gt;
** max (größter Wert innerhalb des poll-delay, manchmal leer bei zu kleinem poll-delay)&lt;br /&gt;
** average (Durchschnitt der Werte im poll-delay, manchmal leer bei zu kleinem poll-delay)&lt;br /&gt;
** consumption (Verbrauch innerhalb des poll-delays, manchmal leer bei zu kleinem poll-delay)&lt;br /&gt;
* &amp;lt;poll-delay&amp;gt;: Zeitraum, der ausgelesen werden soll in Sekunden&lt;br /&gt;
&lt;br /&gt;
== Beispiele ==&lt;br /&gt;
Ein vollständiges Beispiel für die erforderlichen Definitionen und das daraus resultierende Ergebnis:&lt;br /&gt;
&lt;br /&gt;
=== Momentanverbrauch ===&lt;br /&gt;
Kanal im Volkszaehler, der den Momentanverbrauch per I/R-Lesekopf ermittelt (alle 60 Sekunden, daraus der Mittelwert)&lt;br /&gt;
&lt;br /&gt;
  define Verbrauch_aktuell VOLKSZAEHLER 192.168.178.45 80 635481a0-6fcd-11e2-8587-eda25228f8bf average 60&lt;br /&gt;
  attr Verbrauch_aktuell group Strom&lt;br /&gt;
  attr Verbrauch_aktuell room Volkszaehler&lt;br /&gt;
&lt;br /&gt;
=== Logdatei ===&lt;br /&gt;
Definition der Logdatei, aus der die Grafik erzeugt werden kann:&lt;br /&gt;
&lt;br /&gt;
  define FileLog_Verbrauch_aktuell FileLog ./log/Verbrauch_aktuell-%Y-%m.log Verbrauch_aktuell&lt;br /&gt;
  attr FileLog_Verbrauch_aktuell logtype text&lt;br /&gt;
  attr Verbrauch_aktuell room Volkszaehler&lt;br /&gt;
&lt;br /&gt;
=== Der Graph dazu ===&lt;br /&gt;
  define FilePlot_Verbrauch_aktuell weblink fileplot FileLog_Verbrauch_aktuell:Volkszaehler:CURRENT&lt;br /&gt;
  attr FilePlot_Verbrauch_aktuell label &amp;quot;Stromverbrauch: $data{currval1}&amp;quot;&lt;br /&gt;
  attr FilePlot_Verbrauch_aktuell room Volkszaehler&lt;br /&gt;
&lt;br /&gt;
=== Zählerstand ===&lt;br /&gt;
Kanal im Volkszaehler, der den Zählerstand per I/R-Lesekopf ermittelt, jede Stunde davon der letzte Wert.&lt;br /&gt;
&lt;br /&gt;
  define Zaehlerstand VOLKSZAEHLER 192.168.178.45 80 ebb9c9b0-7058-11e2-b5ed-d12ec87a3a7f last 1800&lt;br /&gt;
  attr Zaehlerstand group Strom&lt;br /&gt;
  attr Zaehlerstand room Volkszaehler&lt;br /&gt;
&lt;br /&gt;
=== Verbrauch ===&lt;br /&gt;
Kanal im Volkszaehler, der den Zählerstand per I/R-Lesekopf ermittelt, alle 24 Stunden davon der Verbrauch.&lt;br /&gt;
&lt;br /&gt;
  define Verbrauch_24h VOLKSZAEHLER 192.168.178.45 80 635481a0-6fcd-11e2-8587-eda25228f8bf consumption 86400&lt;br /&gt;
  attr Verbrauch_24h group Strom&lt;br /&gt;
  attr Verbrauch_24h room Volkszaehler&lt;br /&gt;
&lt;br /&gt;
=== Ergebnis ===&lt;br /&gt;
[[Datei:23_volkszaehler.JPG|mini|zentriert|hochkant=3.0|Strom- und Gasverbrauch aus Volkszählerdaten generiert - Beispieldarstellung]]&lt;br /&gt;
&lt;br /&gt;
== Daten mit Volkszaehler loggen ==&lt;br /&gt;
Hier eine Möglichkeit mit einem notify Temperaturen (oder andere Messwerte) an die Middelware vom Volkszaehler zu schicken um die Daten über ein Volkszaehler Frontend auswerten zu können (&#039;&#039;&#039;Achtung&#039;&#039;&#039;: folgender Kode-Schnipsel funktioniert nur, wenn 23_VOLKSZAEHLER installiert und geladen wurde):  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Perl&amp;quot;&amp;gt;&lt;br /&gt;
   .*:temperature.* {&lt;br /&gt;
    # return &amp;quot;Heizung $NAME&amp;quot; if $NAME =~ /\A.{3}Heizung/; # [[MAX]] Geräte ausschließen. Workaround für aufgebrauchte credits.&lt;br /&gt;
    my $base_url = AttrVal(&#039;vz&#039;, &#039;vz_URL&#039;, undef);&lt;br /&gt;
    my $temp = ReadingsVal($NAME, &#039;temperature&#039;, undef);&lt;br /&gt;
    my $uuid = AttrVal($NAME, &#039;vz_UUID&#039;, undef);&lt;br /&gt;
    unless (defined($uuid)) {&lt;br /&gt;
      my $create_url = $base_url . &#039;/channel.json?type=temperature&amp;amp;title=&#039; . $NAME . &#039;&amp;amp;public=on&amp;amp;style=lines&amp;amp;operation=add&#039;;&lt;br /&gt;
      Log 5, $create_url;&lt;br /&gt;
      my $response = decode_json(get($create_url));&lt;br /&gt;
      $uuid = $response-&amp;gt;{entity}-&amp;gt;{uuid};&lt;br /&gt;
      $attr{$NAME}{&#039;vz_UUID&#039;} = $uuid;&lt;br /&gt;
      Log 4, &amp;quot;created $uuid for $NAME&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    my $update_url = $base_url . &#039;/data/&#039; . $uuid . &#039;.json?operation=add&amp;amp;value=&#039; . $temp;&lt;br /&gt;
    Log 5, $update_url;&lt;br /&gt;
    Log 4, get($update_url);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Volkszaehler-URL wird in einem Attribut (vz_URL) eines [[dummy|dummies]] gespeichert, welches vorher angelegt werden muss.&lt;br /&gt;
&lt;br /&gt;
Jedes Thermometer, das auch im Volkszaehler erscheinen soll, muss nun nur noch im Volkszaehler angelegt werden und die UUID als Attribut (vz_UUID) des Thermometers gespeichert werden. Dieser Schritt kann auch ausgelassen werden. In diesem Fall wird ein neues Thermometer automatisch angelegt.&lt;br /&gt;
&lt;br /&gt;
  define vz dummy&lt;br /&gt;
  attr vz vz_URL http://localhost/volkszaehler.org/htdocs/middleware.php&lt;br /&gt;
  attr vz vz_UUID XXXXXXXXXXXXXXXXXXXXXXXXXXX&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* Volkszähler [http://www.volkszaehler.org Homepage]&lt;br /&gt;
* [https://github.com/bgewehr/fhem FHEM Module] für Volkszähler von &amp;quot;bgewehr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Other Components]]&lt;br /&gt;
[[Kategorie:HOWTOS]]&lt;br /&gt;
[[Kategorie:Energieverbrauchsmessung]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=36146</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=36146"/>
		<updated>2021-10-24T19:48:05Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsNum */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum&amp;lt;/code&amp;gt; extrahiert den numerischen Teil des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück, wenn er existiert. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabewert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;; überzählige Stellen werden mit 0 aufgefüllt - round ist daher kein round im strikt mathematischen Sinne, sondern bietet zusätzlich eine Formatierung.&lt;br /&gt;
&lt;br /&gt;
==== Beispiele ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert));&lt;br /&gt;
# = 123.45&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(baz), q(Kein Wert));&lt;br /&gt;
# = &amp;quot;Kein Wert&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 0);&lt;br /&gt;
# = 123&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 1);&lt;br /&gt;
# = 123.5&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.45000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123 °C&amp;quot;&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.00000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert oder kein numerischer Teil ermittelt werden konnte.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Fallstricke ====&lt;br /&gt;
Der Rückgabewert muss nicht unbedingt ein numerischer Wert sein, wenn als &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; kein numerischer Wert oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wurde. Vergleiche mit numerischen Operatoren werden dann ggf. ein Warning erzeugen.&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Lese aus dem Reading baz, nicht bar, wird fehlschlagen&lt;br /&gt;
if ( ReadingsNum(q(foo), q(baz), q(Kein Wert), 0) == 123.5 ) {&lt;br /&gt;
    say q(Wert ist 123.5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Argument &amp;quot;Kein Wert&amp;quot; isn&#039;t numeric in numeric eq (==)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; wird direkt, d.h. ohne Validierung, in den [https://perldoc.perl.org/functions/sprintf format string] in &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt; übernommen und ausgewertet.&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), q{%%p});&lt;br /&gt;
# Evaluiert %p zu einer Speicheradresse, z.B. 7fa1fb03d738f&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), q(foo));&lt;br /&gt;
# = 123oof&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35935</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35935"/>
		<updated>2021-07-30T15:24:21Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* Fallstricke */ Weiteres Beispiel für Fallstrick hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum&amp;lt;/code&amp;gt; extrahiert den numerischen Teil des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück, wenn er existiert. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;; überzählige Stellen werden mit 0 aufgefüllt - round ist daher kein round im strikt mathematischen Sinne, sondern bietet zusätzlich eine Formatierung.&lt;br /&gt;
&lt;br /&gt;
==== Beispiele ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert));&lt;br /&gt;
# = 123.45&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(baz), q(Kein Wert));&lt;br /&gt;
# = &amp;quot;Kein Wert&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 0);&lt;br /&gt;
# = 123&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 1);&lt;br /&gt;
# = 123.5&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.45000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123 °C&amp;quot;&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.00000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert oder kein numerischer Teil ermittelt werden konnte.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Fallstricke ====&lt;br /&gt;
Der Rückgabewert muss nicht unbedingt ein numerischer Wert sein, wenn als &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; kein numerischer Wert oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wurde. Vergleiche mit numerischen Operatoren werden dann ggf. ein Warning erzeugen.&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Lese aus dem Reading baz, nicht bar, wird fehlschlagen&lt;br /&gt;
if ( ReadingsNum(q(foo), q(baz), q(Kein Wert), 0) == 123.5 ) {&lt;br /&gt;
    say q(Wert ist 123.5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Argument &amp;quot;Kein Wert&amp;quot; isn&#039;t numeric in numeric eq (==)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; wird direkt, d.h. ohne Validierung, in den [https://perldoc.perl.org/functions/sprintf format string] in &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt; übernommen und ausgewertet.&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), q{%%p});&lt;br /&gt;
# Evaluiert %p zu einer Speicheradresse, z.B. 7fa1fb03d738f&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), q(foo));&lt;br /&gt;
# = 123oof&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35934</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35934"/>
		<updated>2021-07-30T10:49:52Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsNum */ Hinweis auf Übergaben an $round&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum&amp;lt;/code&amp;gt; extrahiert den numerischen Teil des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück, wenn er existiert. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;; überzählige Stellen werden mit 0 aufgefüllt - round ist daher kein round im strikt mathematischen Sinne, sondern bietet zusätzlich eine Formatierung.&lt;br /&gt;
&lt;br /&gt;
==== Beispiele ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert));&lt;br /&gt;
# = 123.45&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(baz), q(Kein Wert));&lt;br /&gt;
# = &amp;quot;Kein Wert&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 0);&lt;br /&gt;
# = 123&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 1);&lt;br /&gt;
# = 123.5&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.45000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123 °C&amp;quot;&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.00000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert oder kein numerischer Teil ermittelt werden konnte.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Fallstricke ====&lt;br /&gt;
Der Rückgabewert muss nicht unbedingt ein numerischer Wert sein, wenn als &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; kein numerischer Wert oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wurde. Vergleiche mit numerischen Operatoren werden dann ggf. ein Warning erzeugen.&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Lese aus dem Reading baz, nicht bar, wird fehlschlagen&lt;br /&gt;
if ( ReadingsNum(q(foo), q(baz), q(Kein Wert), 0) == 123.5 ) {&lt;br /&gt;
    say q(Wert ist 123.5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Argument &amp;quot;Kein Wert&amp;quot; isn&#039;t numeric in numeric eq (==)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; wird direkt in den [https://perldoc.perl.org/functions/sprintf format string] in &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt; übernommen und ausgewertet.&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Lese aus dem Reading baz, nicht bar, wird fehlschlagen&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), q{%%p});&lt;br /&gt;
&lt;br /&gt;
# Evaluiert %p zu einer Speicheradresse, z.B. 7fa1fb03d738f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35933</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35933"/>
		<updated>2021-07-30T10:44:23Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsNum */ Weitere Beispiele hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum&amp;lt;/code&amp;gt; extrahiert den numerischen Teil des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück, wenn er existiert. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;; überzählige Stellen werden mit 0 aufgefüllt - round ist daher kein round im strikt mathematischen Sinne, sondern bietet zusätzlich eine Formatierung.&lt;br /&gt;
&lt;br /&gt;
==== Beispiele ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert));&lt;br /&gt;
# = 123.45&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(baz), q(Kein Wert));&lt;br /&gt;
# = &amp;quot;Kein Wert&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 0);&lt;br /&gt;
# = 123&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 1);&lt;br /&gt;
# = 123.5&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.45000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123 °C&amp;quot;&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.00000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert oder kein numerischer Teil ermittelt werden konnte.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Fallstricke ====&lt;br /&gt;
Der Rückgabewert muss nicht unbedingt ein numerischer Wert sein, wenn als &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; kein numerischer Wert oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wurde. Vergleiche mit numerischen Operatoren werden dann ggf. ein Warning erzeugen.&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Lese aus dem Reading baz, nicht bar, wird fehlschlagen&lt;br /&gt;
if ( ReadingsNum(q(foo), q(baz), q(Kein Wert), 0) == 123.5 ) {&lt;br /&gt;
    say q(Wert ist 123.5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Argument &amp;quot;Kein Wert&amp;quot; isn&#039;t numeric in numeric eq (==)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35932</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35932"/>
		<updated>2021-07-30T10:41:10Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsNum */ Fallstricke hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum&amp;lt;/code&amp;gt; extrahiert den numerischen Teil des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück, wenn er existiert. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;; überzählige Stellen werden mit 0 aufgefüllt - round ist daher kein round im mathematischen Sinne, sondern eine Formatierung.&lt;br /&gt;
&lt;br /&gt;
==== Beispiele ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert));&lt;br /&gt;
# = 123.45&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(baz), q(Kein Wert));&lt;br /&gt;
# = Kein Wert&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 0);&lt;br /&gt;
# = 123&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 1);&lt;br /&gt;
# = 123.5&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.45000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert oder kein numerischer Teil ermittelt werden konnte.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Fallstricke ====&lt;br /&gt;
Der Rückgabewert muss nicht unbedingt ein numerischer Wert sein, wenn als &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; kein numerischer Wert oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wurde. Vergleiche mit numerischen Operatoren werden dann ggf. ein Warning erzeugen.&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.45 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Lese aus dem Reading baz, nicht bar, wird fehlschlagen&lt;br /&gt;
if ( ReadingsNum(q(foo), q(baz), q(Kein Wert), 0) == 123.5 ) {&lt;br /&gt;
    say q(Wert ist 123.5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Argument &amp;quot;Kein Wert&amp;quot; isn&#039;t numeric in numeric eq (==)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35931</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35931"/>
		<updated>2021-07-29T11:52:08Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsAge */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum&amp;lt;/code&amp;gt; extrahiert den numerischen Teil des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück, wenn er existiert. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;; überzählige Stellen werden mit 0 aufgefüllt - round ist daher kein round im mathematischen Sinne, sondern eine Formatierung.&lt;br /&gt;
&lt;br /&gt;
==== Beispiele ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.42 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert));&lt;br /&gt;
# = 123.42&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(baz), q(Kein Wert));&lt;br /&gt;
# = Kein Wert&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 0);&lt;br /&gt;
# = 123&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 1);&lt;br /&gt;
# = 123.4&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.42000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Parameter ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Rückgabewert ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert oder kein numerischer Teil ermittelt werden konnte.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35930</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35930"/>
		<updated>2021-07-29T11:51:08Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsNum */ Hinweis darauf, dass round() kein mathematisches Runden bietet, sondern eine Formatierung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum&amp;lt;/code&amp;gt; extrahiert den numerischen Teil des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück, wenn er existiert. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;; überzählige Stellen werden mit 0 aufgefüllt - round ist daher kein round im mathematischen Sinne, sondern eine Formatierung.&lt;br /&gt;
&lt;br /&gt;
Beispiele:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.42 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert));&lt;br /&gt;
# = 123.42&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(baz), q(Kein Wert));&lt;br /&gt;
# = Kein Wert&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 0);&lt;br /&gt;
# = 123&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 1);&lt;br /&gt;
# = 123.4&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.42000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert oder kein numerischer Teil ermittelt werden konnte.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35929</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35929"/>
		<updated>2021-07-29T11:35:50Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsNum */ Beispiele hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum&amp;lt;/code&amp;gt; extrahiert den numerischen Teil des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück, wenn er existiert. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;; überzählige Stellen werden mit 0 aufgefüllt.&lt;br /&gt;
&lt;br /&gt;
Beispiele:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
# Device foo, Reading bar, Wert &amp;quot;123.42 °C&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert));&lt;br /&gt;
# = 123.42&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(baz), q(Kein Wert));&lt;br /&gt;
# = Kein Wert&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 0);&lt;br /&gt;
# = 123&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 1);&lt;br /&gt;
# = 123.4&lt;br /&gt;
&lt;br /&gt;
ReadingsNum(q(foo), q(bar), q(Kein Wert), 5);&lt;br /&gt;
# = 123.42000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert oder kein numerischer Teil ermittelt werden konnte.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35928</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35928"/>
		<updated>2021-07-29T09:37:10Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsNum */ Klargestellt, welche Teile aus einem Readings extrahiert und wie sie zurückgeliefert werden&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum&amp;lt;/code&amp;gt; extrahiert den numerischen Teil des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück, wenn er existiert. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert oder kein numerischer Teil ermittelt werden konnte.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35927</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35927"/>
		<updated>2021-07-29T09:08:14Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsNum */ Link auf FHEM round() um Missverständnisse zu vermeiden&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum()&amp;lt;/code&amp;gt; extrahiert einen numerischen Wert aus dem Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden. Verwendet wird hierzu die FHEM-eigene Funktion &amp;lt;code&amp;gt;[https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm#L239 round]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein numerischer Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$number&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Numerischer Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35926</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35926"/>
		<updated>2021-07-29T09:05:23Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* ReadingsNum */ $round Parameter hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsNum($name, $reading, $default, $round);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt;ReadingsNum()&amp;lt;/code&amp;gt; extrahiert einen numerischen Wert aus dem Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Es ist möglich, den Rückgabe wert durch Angabe von &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt; Stellen zu runden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein numerischer Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$round&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Der ermittelte Wert, ob Standard oder aus einem Reading, wird auf &#039;&#039;$round&#039;&#039; Anzahl Stellen gerundet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$number&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Numerischer Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=FHEMWEB/Widgets&amp;diff=35633</id>
		<title>FHEMWEB/Widgets</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=FHEMWEB/Widgets&amp;diff=35633"/>
		<updated>2021-04-28T13:56:40Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Typos gefixt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Widgets sind Frontendelemente, die der Dateneingabe und -anzeige dienen. Die hier gezeigten Frontendelemente werden durch [[FHEMWEB]] ([[PGM2]]) bereitgestellt.&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
Die Syntax der Widgets ist unter dem Attribut [https://fhem.de/commandref_DE.html#widgetOverride widgetOverride] in der Befehlreferenz beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Verwendung ==&lt;br /&gt;
Viele Module (u.a. [[DOIF]], [[dummy]], [[MQTT_DEVICE]], [[MQTT2_DEVICE]], [[MYSENSORS_DEVICE]], [[readingsGroup]]) bieten die Möglichkeit eine Benutzerschnittstelle zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Widgets werden über &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;:&amp;lt;modifier&amp;gt;&amp;lt;/code&amp;gt;-Paare an [[Readings]] oder [[Attribute]] gebunden, dabei ist:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/code&amp;gt; ein Readingsname, ein Attribut oder ein Mapping-Argument.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;modifier&amp;gt;&amp;lt;/code&amp;gt; ein Widget einschliesslich Parameter.&lt;br /&gt;
&lt;br /&gt;
Bei der Erstellung spielen verschiedene Attribute zusammen:&lt;br /&gt;
&lt;br /&gt;
* Mit [[readingList]] (bzw. bei Modulen, die dies nicht kennen: widgetOverride) ist es möglich den Set-Befehl auf [[Readings]] zu erweitern, s. [https://fhem.de/commandref_DE.html#readingList readingList].&lt;br /&gt;
* Mit [[setList]] (bzw. widgetOverride) werden die Widgets einem Reading zugeordnet und parametrisiert, s. [https://fhem.de/commandref_DE.html#setList setList].&lt;br /&gt;
* Mit [[webCmd]] werden die Widgets angezeigt, s. [https://fhem.de/commandref_DE.html#setList webCmd].&lt;br /&gt;
* Mit [[webCmdLabel]] werden die Widgets beschriftet und tabellarisch angeordnet, s. [https://fhem.de/commandref_DE.html#webCmdLabel webCmdLabel].&lt;br /&gt;
* Mit [[widgetOverride]] ist es möglich, die im Modul festgelegten Widgets zu überschreiben, s. [https://fhem.de/commandref_DE.html#widgetOverride widgetOverride].&lt;br /&gt;
* Mit [[eventMap]] ist es möglich Widgets an Mapping-Argumente zu binden, s. [https://fhem.de/commandref_DE.html#eventMap eventMap] und {{Link2Forum|Topic=76755|LinkText=eventMap und Widget-Anbindung}} .&lt;br /&gt;
Das Zusammenspiel dieser Attribute ist u.A. im Artikel [[DeviceOverview anpassen#webCmd .26 Co|DeviceOverview anpassen]] näher erläutert.&lt;br /&gt;
&lt;br /&gt;
== Zusammenstellung der Widgets ==&lt;br /&gt;
&lt;br /&gt;
Die Bildschirmkopie zeigt das Benutzerinterface des Dummys mit den Widgets&lt;br /&gt;
[[Datei:fhemweb_widgets.png]]&lt;br /&gt;
&lt;br /&gt;
=== weitere Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;knob&#039;&#039;&#039;, siehe http://anthonyterrien.com/knob/&lt;br /&gt;
* &#039;&#039;&#039;colorpicker&#039;&#039;&#039;, siehe [[Color]]&lt;br /&gt;
&lt;br /&gt;
== Das Beispiel für [[DOIF/Import_von_Code_Snippets|Raw definition]] zum Ausprobieren ==&lt;br /&gt;
&lt;br /&gt;
In der vorstehenden Abbildung fehlt das Look and Feel der Widgets. Mit dem folgenden Code-Snippet zum Ausprobieren, wird dies ergänzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmod widgets dummy&lt;br /&gt;
attr widgets readingList 00select 01select 02selectnumbers 03selectnumbers 04textField 05textFieldNL 06textField-long 07textFieldNL-long 08slider 09multiple 10multiple-strict 11knob 12sortable 13sortable-strict 14sortable-given 15uzsuToggle 16uzsuSelect 17uzsuSelectRadio 18uzsuDropDown 19colorpicker_RGB 19colorpicker_HSV 19colorpicker_CT 19colorpicker_HUE 19colorpicker_BRI 20time 21iconRadio 21iconRadio_use4icon 22iconSwitch 23iconLabel 24iconButtons 24iconButtons_use4icon 25bitfield&lt;br /&gt;
attr widgets room 1_Widgets&lt;br /&gt;
attr widgets setList 00select:1,2,3,4,5,a,b,c,def,hik \&lt;br /&gt;
01select:select,1,2,3,4,5,a,b,c,def,hik \&lt;br /&gt;
02selectnumbers:selectnumbers,7,0.5,30,1,lin \&lt;br /&gt;
03selectnumbers:selectnumbers,1,0.0625,140000,0,log10 \&lt;br /&gt;
04textField:textField \&lt;br /&gt;
05textFieldNL:textFieldNL\&lt;br /&gt;
06textField-long:textField-long \&lt;br /&gt;
07textFieldNL-long:textFieldNL-long \&lt;br /&gt;
08slider:slider,7,0.5,30,1 \&lt;br /&gt;
09multiple:multiple,shirt,shoes,skirt,trowsers \&lt;br /&gt;
10multiple-strict:multiple-strict,red,green,blue,yellow \&lt;br /&gt;
11knob:knob,min:0,max:360,width:50,height:50,step:1,lineCap:round,angleOffset:180,cursor:3,thickness:.3 \&lt;br /&gt;
12sortable:sortable,blue,shirt,white,shoes,brown,skirt,black,jeans\&lt;br /&gt;
13sortable-strict:sortable-strict,blue,shirt,white,shoes,brown,skirt,black,jeans\&lt;br /&gt;
14sortable-given:sortable-given,blue,shirt,white,shoes,brown,skirt,black,jeans\&lt;br /&gt;
15uzsuToggle:uzsuToggle,ON,OFF\&lt;br /&gt;
16uzsuSelect:uzsuSelect,blue,shirt,white,shoes,brown,skirt,black,jeans\&lt;br /&gt;
17uzsuSelectRadio:uzsuSelectRadio,MW,KW,UKW\&lt;br /&gt;
18uzsuDropDown:uzsuDropDown,red,green,blue,yellow \&lt;br /&gt;
19colorpicker_RGB:colorpicker,RGB \&lt;br /&gt;
19colorpicker_HSV:colorpicker,HSV \&lt;br /&gt;
19colorpicker_CT:colorpicker,CT,2000,10,6500 \&lt;br /&gt;
19colorpicker_HUE:colorpicker,HUE,0,1,359 \&lt;br /&gt;
19colorpicker_BRI:colorpicker,BRI,0,1,100 \&lt;br /&gt;
20time:time \&lt;br /&gt;
21iconRadio:iconRadio,#808080,10,fts_shutter_10@FFA500,20,fts_shutter_20@orange,30,fts_shutter_30@orange,40,fts_shutter_40@orange,50,fts_shutter_50@orange,60,fts_shutter_60@orange,70,fts_shutter_70@orange,80,fts_shutter_80@orange,90,fts_shutter_90@orange,100,fts_shutter_100@orange \&lt;br /&gt;
21iconRadio_use4icon:iconRadio,use4icon@808080,10,fts_shutter_10@FFA500,20,fts_shutter_20@orange,30,fts_shutter_30@orange,40,fts_shutter_40@orange,50,fts_shutter_50@orange,60,fts_shutter_60@orange,70,fts_shutter_70@orange,80,fts_shutter_80@orange,90,fts_shutter_90@orange,100,fts_shutter_100@orange \&lt;br /&gt;
22iconSwitch:iconSwitch,wide#open,@red,half#open,fts_shutter_50@%23cd2906,totally#closed,fts_shutter_100@magenta,half#closed, \&lt;br /&gt;
23iconLabel:iconLabel,wide#open,@red,half#open,fts_shutter_50@%23cd2906,totally#closed,fts_shutter_100@magenta,half#closed,\&lt;br /&gt;
24iconButtons:iconButtons,orange,Bad,sani_heating@green,Wohnzimmer_1,sani_heating@green,Wohnzimmer_2,sani_heating@green,Esszimmer,sani_heating@green,Diele,sani_heating@green,Gäste_WC,sani_heating@green,Büro,sani_heating@green,Wintergarten,sani_heating@green,Werkstatt,sani_heating@green,Schlafzimmer,sani_heating@green \&lt;br /&gt;
24iconButtons_use4icon:iconButtons,use4icon@red,Bad,sani_heating@0000FF,Wohnzimmer_1,sani_heating@blue,Wohnzimmer_2,sani_heating@blue,Esszimmer,sani_heating@blue,Diele,sani_heating@blue,Gäste_WC,sani_heating@blue,Büro,sani_heating@blue,Wintergarten,sani_heating@blue,Werkstatt,sani_heating@blue,Schlafzimmer,sani_heating@0000FF\&lt;br /&gt;
25bitfield:bitfield&lt;br /&gt;
attr widgets userReadings 23iconLabel:22iconSwitch.* {ReadingsVal($name,&amp;quot;22iconSwitch&amp;quot;,&amp;quot;wideopen&amp;quot;)}&lt;br /&gt;
attr widgets webCmd 00select:01select:02selectnumbers:03selectnumbers:04textField:05textFieldNL:06textField-long:07textFieldNL-long:08slider:20time:09multiple:10multiple-strict:11knob:12sortable:13sortable-strict:14sortable-given:15uzsuToggle:16uzsuSelect:17uzsuSelectRadio:18uzsuDropDown:19colorpicker_RGB:19colorpicker_HSV:19colorpicker_CT:19colorpicker_HUE:19colorpicker_BRI:21iconRadio:21iconRadio_use4icon:24iconButtons:24iconButtons_use4icon:22iconSwitch:23iconLabel:25bitfield&lt;br /&gt;
attr widgets webCmdLabel select (default)\&lt;br /&gt;
:select (explicit)\&lt;br /&gt;
:selectnumbers (linear)\&lt;br /&gt;
:selectnumbers (logarithmic)\&lt;br /&gt;
:textField\&lt;br /&gt;
:textFieldNL (no label)\&lt;br /&gt;
:textField-long (multi-line)\&lt;br /&gt;
:textFieldNL-long (multi-line,no label)\&lt;br /&gt;
:slider\&lt;br /&gt;
:time\&lt;br /&gt;
:multiple\&lt;br /&gt;
:multiple-strict\&lt;br /&gt;
:knob\&lt;br /&gt;
:sortable\&lt;br /&gt;
:sortable-strict\&lt;br /&gt;
:sortable-given\&lt;br /&gt;
:uzsuToggle\&lt;br /&gt;
:uzsuSelect\&lt;br /&gt;
:uzsuSelectRadio\&lt;br /&gt;
:uzsuDropDown\&lt;br /&gt;
:colorpicker RGB\&lt;br /&gt;
:colorpicker HSV\&lt;br /&gt;
:colorpicker Farbtemperatur\&lt;br /&gt;
:colorpicker Farbton\&lt;br /&gt;
:colorpicker Helligkeit\&lt;br /&gt;
:iconRadio\&lt;br /&gt;
:iconRadio prefix use4icon\&lt;br /&gt;
:iconButtons\&lt;br /&gt;
:iconButtons prefix use4icon\&lt;br /&gt;
:iconSwitch\&lt;br /&gt;
:iconLabel\&lt;br /&gt;
:bitfield&lt;br /&gt;
attr widgets widgetOverride readingList|setList|webCmd|webCmdLabel:textField-long&lt;br /&gt;
&lt;br /&gt;
setstate widgets iconSwitch wide open&lt;br /&gt;
setstate widgets 2017-08-29 20:32:22 00select 1&lt;br /&gt;
setstate widgets 2017-08-29 20:43:04 01select 2&lt;br /&gt;
setstate widgets 2017-08-24 17:38:22 02selectnumbers 10.5&lt;br /&gt;
setstate widgets 2017-08-24 17:38:51 03selectnumbers 64938&lt;br /&gt;
setstate widgets 2017-10-06 16:37:24 04textField Hello&lt;br /&gt;
setstate widgets 2017-08-24 17:39:22 05textField Hallo&lt;br /&gt;
setstate widgets 2017-10-06 16:37:25 05textFieldNL Hello&lt;br /&gt;
setstate widgets 2017-08-24 17:57:54 06textField-long Hello&lt;br /&gt;
setstate widgets 2017-10-06 16:37:23 07textFieldNL-long Hello&lt;br /&gt;
setstate widgets 2017-10-06 16:37:42 08slider 19.5&lt;br /&gt;
setstate widgets 2017-08-24 18:22:40 09multiple shirt,shoes&lt;br /&gt;
setstate widgets 2017-08-24 18:22:57 10multiple-strict red,green&lt;br /&gt;
setstate widgets 2019-07-30 20:08:44 11knob 120&lt;br /&gt;
setstate widgets 2017-08-29 08:11:40 12sortable shirt,brown,skirt,white,shoes,black,jeans&lt;br /&gt;
setstate widgets 2017-08-24 18:48:17 13sortable-strict blue,white,shirt,shoes,brown,skirt,black,jeans&lt;br /&gt;
setstate widgets 2017-08-24 18:49:34 14sortable-given blue,shirt,white,shoes,brown,skirt,black,jeans&lt;br /&gt;
setstate widgets 2017-08-27 13:37:44 15uzsuToggle OFF&lt;br /&gt;
setstate widgets 2017-09-01 10:44:22 16uzsuSelect shoes,skirt,jeans&lt;br /&gt;
setstate widgets 2017-08-31 00:28:20 17uzsuSelectRadio MW&lt;br /&gt;
setstate widgets 2017-12-31 08:30:45 18uzsuDropDown blue&lt;br /&gt;
setstate widgets 2017-08-24 20:54:43 19colorpicker ac2ab0&lt;br /&gt;
setstate widgets 2017-10-19 20:50:12 19colorpicker_BRI 100&lt;br /&gt;
setstate widgets 2017-10-07 07:56:31 19colorpicker_CT 5100&lt;br /&gt;
setstate widgets 2017-10-19 20:51:24 19colorpicker_HSV 822828&lt;br /&gt;
setstate widgets 2017-10-19 20:50:56 19colorpicker_HUE 185&lt;br /&gt;
setstate widgets 2017-10-19 20:50:47 19colorpicker_RGB 4b14ff&lt;br /&gt;
setstate widgets 2017-08-29 08:11:19 20time 12:00&lt;br /&gt;
setstate widgets 2019-07-30 20:08:01 21iconRadio 10&lt;br /&gt;
setstate widgets 2019-07-30 20:08:10 21iconRadio_use4icon 50&lt;br /&gt;
setstate widgets 2017-09-20 18:59:29 22iconButtons Wohnzimmer_1,Esszimmer,Gäste_WC,Wintergarten,Schlafzimmer&lt;br /&gt;
setstate widgets 2019-07-30 20:07:38 22iconSwitch half open&lt;br /&gt;
setstate widgets 2019-07-30 20:07:38 23iconLabel half open&lt;br /&gt;
setstate widgets 2017-09-01 11:40:52 23iconselectradio 10&lt;br /&gt;
setstate widgets 2019-07-30 20:07:47 24iconButtons Bad,Wohnzimmer_2,Diele,Büro,Werkstatt&lt;br /&gt;
setstate widgets 2019-07-30 20:07:49 24iconButtons_use4icon Wohnzimmer_1,Esszimmer,Büro,Werkstatt&lt;br /&gt;
setstate widgets 2019-08-06 13:48:37 25bitfield 0&lt;br /&gt;
setstate widgets 2017-11-25 01:41:29 iconSwitch half closed&lt;br /&gt;
setstate widgets 2017-11-25 01:42:52 state iconSwitch wide open&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beigesteuerte Widgets ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Forenthread [https://forum.fhem.de/index.php?topic=35736.0 neues DateTimePicker Widget] [[Datei:datetimepicker.png]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;br /&gt;
[[Kategorie:Glossary]]&lt;br /&gt;
[[Kategorie:HOWTOS]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=HMCCU&amp;diff=35631</id>
		<title>HMCCU</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=HMCCU&amp;diff=35631"/>
		<updated>2021-04-28T12:09:00Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Fehlender Doppelpunkt in der Beschreibung zu ccuGetVars ergänzt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul HMCCU ermöglicht zusammen mit weiteren Modulen eine Integration der [[HomeMatic]] CCU Zentrale sowie der dort angelernten Geräte in FHEM. {{Infobox Modul&lt;br /&gt;
|ModPurpose=Anbindung HomeMatic CCU an FHEM&lt;br /&gt;
|ModType=d&lt;br /&gt;
|ModCmdRef=HMCCU&lt;br /&gt;
|ModForumArea=HomeMatic&lt;br /&gt;
|ModTechName=88_HMCCU.pm &lt;br /&gt;
|ModOwner=zap ({{Link2FU|10980|Forum}} / [[Benutzer Diskussion:Zap|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
==Einführung==&lt;br /&gt;
===Übersicht===&lt;br /&gt;
Das Modul [[HMCCU]] ermöglicht zusammen mit den Client Modulen → [[HMCCUDEV]], HMCCUCHN und HMCCUPROCRPC eine Integration der [[HomeMatic]] CCU Zentrale sowie der dort angelernten Geräte in FHEM. Im Einzelnen werden folgende Funktionen unterstützt:&lt;br /&gt;
&lt;br /&gt;
* Unterstützt Hard- und Software CCUs inkl. CCU3, YAHM, piVCCU und RaspberryMatic&lt;br /&gt;
* Unterstützung der Protokolle BidCos, Wired und [[HomeMatic IP|HM-IP]]&lt;br /&gt;
* Unterstützung von CUxD, OSRAM und Philips Hue Devices in der CCU&lt;br /&gt;
* Unterstützung von HVL (HomeMatic Virtual Layer)&lt;br /&gt;
* Unterstützung von CCU Gerätegruppen bzw. virtuellen Geräten (Heizung, Rauchmelder)&lt;br /&gt;
* Automatische Aktualisierung von Gerätezuständen in FHEM per RPC-Server&lt;br /&gt;
* Automatische Konvertierung und Skalierung von Werten beim Lesen und Schreiben&lt;br /&gt;
* Lesen und Schreiben von CCU Systemvariablen&lt;br /&gt;
* Ausführen von CCU Programmen&lt;br /&gt;
* Ausführen von HomeMatic Scripts auf der CCU&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Module haben folgende Aufgaben:&lt;br /&gt;
&lt;br /&gt;
* HMCCU: Kommunikation zwischen FHEM und CCU (I/O Device)&lt;br /&gt;
* HMCCURPCPROC: RPC-Server zum Empfang von Events der CCU&lt;br /&gt;
* HMCCUDEV: Definition von FHEM Devices für HomeMatic Geräte&lt;br /&gt;
* HMCCUCHN: Definition von FHEM Devices für einzelne Kanäle von HomeMatic Geräten&lt;br /&gt;
* HMCCUConf: Templates mit Default Attributen für bestimmte HomeMatic Gerätetypen&lt;br /&gt;
&lt;br /&gt;
===Geräte, Kanäle und Datenpunkte===&lt;br /&gt;
Geräte in der HomeMatic CCU bestehen aus einem oder mehreren Kanälen. Ein Kanal wiederum hat einen oder mehrere Datenpunkte. Über diese Datenpunkte kann ein Gerät gesteuert oder Statusinformationen ausgelesen werden. Sofern ein Datenpunkt lesbar ist, kann er als Reading in einem HMCCUCHN oder HMCCUDEV Device dargestellt werden. Ausgehend von dieser Abbildung in der CCU kann man nun entscheiden, ob man ein CCU Gerät mit HMCCUCHN oder HMCCUDEV definiert.&lt;br /&gt;
&lt;br /&gt;
Wenn alle benötigten Datenpunkte eines Gerätes über einen Kanal angesprochen werden können, sollte HMCCUCHN verwendet werden. Mit HMCCUDEV werden alle Kanäle eines Gerätes eingebunden. Außerdem unterstützt HMCCUDEV Rauchmeldergruppen sowie virtuelle Geräte wie z.B. Heizungsgruppen.&lt;br /&gt;
&lt;br /&gt;
Ein Sonderfall ist der Statuskanal 0, der von allen HomeMatic Geräten bereitgestellt wird. Dieser Kanal ist inklusive seiner Datenpunkte sowohl in HMCCUCHN als auch in HMCCUDEV Devices verfügbar.&lt;br /&gt;
{{Hinweis|Im Artikel → [[HMCCU Best Practice]] gibt es einige Tipps für den Einstieg inklusive Schritt-für-Schritt Anleitungen.}}&lt;br /&gt;
&lt;br /&gt;
==Inbetriebnahme==&lt;br /&gt;
===Zu beachten===&lt;br /&gt;
&lt;br /&gt;
* In den CCU Gerätenamen dürfen keine Umlaute verwendet werden. Leerzeichen sind zulässig, können aber u.U. bei einigen Funktionen zu Problemen führen.&lt;br /&gt;
* Namen in der CCU müssen über alle Objekttypen hinweg eindeutig sein. Beispiel: Ein Gerät und ein Raum dürfen nicht den gleichen Namen haben.&lt;br /&gt;
* Nach dem Neustart der CCU muss auch der RPC-Server neu gestartet werden, da die CCU2 bei einem Neustart die registrierten RPC-Server &amp;quot;vergisst&amp;quot;.&lt;br /&gt;
* Vor der Ausführung eines FHEM Updates oder vor der Installation eines CCU Firmware Updates muss der RPC-Server gestoppt werden.&lt;br /&gt;
* Seit der CCU Firmware 2.27.7 sind die Zugriffsmöglichkeiten auf die CCU durch eine Firewall abgesichert. Der Zugriff durch FHEM muss explizit freigeschaltet werden, da HMCCU sonst nicht korrekt funktioniert (s. nächster Abschnitt).&lt;br /&gt;
&lt;br /&gt;
===CCU Firewall Einstellungen===&lt;br /&gt;
Ab CCU Firmware 2.27.7 sind auf der CCU über das WebGUI folgende Einstellungen vorzunehmen:&lt;br /&gt;
* Menü &amp;quot;Einstellungen &amp;gt; Systemsteuerung&amp;quot; aufrufen&lt;br /&gt;
* Button &amp;quot;Firewall konfigurieren&amp;quot; anklicken&lt;br /&gt;
* Bei &amp;quot;Firewall-Richtlinie&amp;quot; den Eintrag &amp;quot;Ports offen&amp;quot; auswählen, andernfalls müssen die notwendigen Ports im Feld &amp;quot;Port-Freigabe&amp;quot; explizit angegeben werden&lt;br /&gt;
* Die Rechte für &amp;quot;HomeMatic XML-RPC API&amp;quot; und &amp;quot;Remote HomeMatic-Script API&amp;quot; auf &amp;quot;Vollzugriff&amp;quot; setzen.&lt;br /&gt;
* Man kann die Rechte auf &amp;quot;Eingeschränkter Zugriff&amp;quot; belassen, muss dann aber im Feld &amp;quot;IP-Adressen für eingeschränkten Zugriff&amp;quot; die IP des FHEM-Servers oder das komplette Subnetz in Subnet-Notation angeben.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich muss in der Systemsteuerung unter &amp;quot;Sicherheit&amp;quot; die Option &amp;quot;Authentifizierung&amp;quot; deaktiviert werden, da HMCCU den Zugriff per Username/Password noch nicht unterstützt.&lt;br /&gt;
&lt;br /&gt;
===Installation===&lt;br /&gt;
Alle HMCCU Module sind Teil von FHEM. HMCCU benötigt die Perl Module RPC::XML::Server und RPC::XML::Client. &lt;br /&gt;
&lt;br /&gt;
Unter debian/raspbian kann das Paket librpc-xml-perl installiert werden&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y librpc-xml-perl&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unter Windows (Strawberry Perl) kann man das Paket RPC::XML mit cpan installieren&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;doscon&amp;quot;&amp;gt;&lt;br /&gt;
cpan install RPC::XML&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Bei der Installation gemäß [[FHEM Installation Windows]] befindet sich cpan man unter &amp;lt;code&amp;gt;&amp;lt;FHEM-Hauptverzeichis&amp;gt;\perl\bin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der interne RPC-Server legt für den Datenaustausch zwischen CCU2 und FHEM Dateien im Verzeichnis /tmp an. Der fhem Prozess benötigt daher Schreibrechte für dieses Verzeichnis. Das Verzeichnis kann mit dem Attribut &#039;&#039;rpcqueue&#039;&#039; geändert werden. Der mit dem Modul HMCCURPCPROC bereitgestellte externe RPC-Server verwendet keine temporären Dateien. Der interne RPC-Server wird ab Version 4.4 nicht mehr unterstützt.&lt;br /&gt;
&lt;br /&gt;
===Definition I/O Device===&lt;br /&gt;
Im ersten Schritt wird ein I/O Device angelegt, das für die Kommunikation zwischen FHEM und der CCU verantwortlich ist. Im folgenden Beispiel wird davon ausgegangen, dass die CCU unter der IP-Adresse 192.168.1.10 erreichbar ist. Das FHEM Device bekommt den Namen „d_ccu“.&lt;br /&gt;
&amp;lt;pre&amp;gt;define d_ccu HMCCU 192.168.1.10&amp;lt;/pre&amp;gt;&lt;br /&gt;
Falls die CCU als Software Service auf dem gleichen Rechner läuft wie FHEM, sollte bei der Definition der Parameter &#039;&#039;ccudelay&#039;&#039; angegeben werden. Die CCU Services brauchen beim Starten länger als FHEM. Durch &#039;&#039;ccudelay&#039;&#039; wird das neu angelegte I/O Device verzögert um die angegebene Anzahl Sekunden initialisiert. Die Vorgabe sind 180 Sekunden. Je nach Installation kann auch ein höherer Wert notwendig sein:&lt;br /&gt;
&amp;lt;pre&amp;gt;define d_ccu HMCCU 192.168.1.10 ccudelay=180&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Start von FHEM wird dadurch nicht verzögert. Die verzögerte Initialisierung kann mit dem Parameter &#039;&#039;delayedinit&#039;&#039; erzwungen werden, greift dann also auch, wenn die CCU beim Start von FHEM erreichbar ist&lt;br /&gt;
&lt;br /&gt;
===RPC Server konfigurieren===&lt;br /&gt;
Im nächsten Schritt wird der RPC-Server konfiguriert und gestartet. Zunächst werden mit dem Attribut &#039;&#039;rpcinterfaces&#039;&#039; die Schnittstellen bzw. Ports festgelegt, für die sich der RPC-Server bei der CCU registrieren soll. Folgende Angaben sind möglich:&lt;br /&gt;
* BidCos-RF&lt;br /&gt;
* BidCos-Wired&lt;br /&gt;
* HmIP-RF&lt;br /&gt;
* CUxD&lt;br /&gt;
* Homegear&lt;br /&gt;
* HVL&lt;br /&gt;
* VirtualDevices&lt;br /&gt;
&#039;&#039;&#039;Wichtig&#039;&#039;&#039;! Die CCU stellt außer BidCos-RF nur die Schnittstellen bereit, für die auch Geräte vorhanden sind. Nicht verwendete Schnittstellen dürfen bei &#039;&#039;rpcinterfaces&#039;&#039; nicht angegeben werden, da sonst der RPC-Server nicht startet. Im Internal &amp;quot;ccuinterfaces&amp;quot; werden nach der Definition des I/O Device alle verfügbaren Schnittstellen angezeigt.&lt;br /&gt;
&lt;br /&gt;
Danach wird durch Setzen des Attributs &#039;&#039;ccuflags&#039;&#039; auf den Wert procrpc der externe RPC-Server aktiviert. Die Verwendung des internen RPC-Servers ist zwar noch möglich, wird jedoch nicht mehr offiziell unterstützt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Externer RPC-Server (HMCCURPCPROC)&#039;&#039;&#039;&lt;br /&gt;
Beim ersten Start dieses RPC-Servers über das I/O Device wird automatisch je Schnittstelle ein Device vom Typ HMCCURPCPROC angelegt. Die Attribute room und group werden vom I/O Device übernommen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RPC-Server starten&#039;&#039;&#039;&lt;br /&gt;
Nun kann der RPC-Server gestartet werden. Dabei wird je RPC-Schnittstelle ein separater fhem.pl Prozess mit eigenem Listening-Port gestartet. Beim ersten Start legt HMCCU für jede unter &#039;&#039;rpcinterfaces&#039;&#039; angegebene Schnittstelle ein Device vom Typ HMCCURPCPROC an. Bei aktivierter Firewall müssen die Ports (s. Attribut &#039;&#039;rpcserverport&#039;&#039;) geöffnet werden.&lt;br /&gt;
&lt;br /&gt;
Alle RPC-Server werden über das I/O Device mit einem Befehl gestartet:&lt;br /&gt;
&amp;lt;pre&amp;gt;set d_ccu rpcserver on&amp;lt;/pre&amp;gt;&lt;br /&gt;
Während des Starts der RPC-Server und der Registrierung bei der CCU kann das I/O Device nur eingeschränkt verwendet werden. Dies wird durch den Status „starting/busy“ angezeigt. Nachdem die RPC-Server gestartet wurden, wechselt der Status zu „running/OK“. Zusätzlich werden im Internal RPCPID die Prozess-IDs der RPC-Server Prozesse gespeichert.&lt;br /&gt;
Anschließend sollte man noch das Attribut &#039;&#039;rpcserver&#039;&#039; auf „on“ setzen, damit die RPC-Server beim Start von FHEM automatisch gestartet werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;attr d_ccu rpcserver on&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Vorgaben für Client Devices===&lt;br /&gt;
Im I/O Device stehen einige Attribute zur Verfügung, über die Vorgaben für Attribute in Client-Devices eingestellt werden können:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Attribut in HMCCU !! Vorgabe für Attribut in&amp;lt;br /&amp;gt;HMCCUDEV/HMCCUCHN !! Default !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| ccudef-hmstatevals || hmstatevals || &#039;^UNREACH!(1 |true):unreachable;^LOW_?BAT!(1|true):warn_battery&#039; || Legt fest, wie der HomeMatic Status eines Client-Device ermittelt wird.&lt;br /&gt;
|-&lt;br /&gt;
| ccudef-readingfilter || ccureadingfilter || .* || Legt fest, welche Datenpunkte eines CCU Gerätes als Readings gespeichert werden&lt;br /&gt;
|-&lt;br /&gt;
| ccudef-readingname || ccureadingname || Kein Default || Ändert den Namen von Readings und/oder ergänzt neue Readings&lt;br /&gt;
|-&lt;br /&gt;
| ccudef-substitute || substitute || Kein Default || Ersetzt Datenpunktwerte vor der Speicherung in Readings.&lt;br /&gt;
|}&lt;br /&gt;
Der Inhalt der HMCCU Attribute wird an die Attribute im Client-Device angehängt. In der Datei HMCCUConf.pm ist ein Default-Template für ein HMCCU Device definiert, das über den Befehl &#039;&#039;&#039;set defaults&#039;&#039;&#039; für das I/O Device angewendet werden kann. Dabei werden die Attribute &#039;&#039;ccudef-*&#039;&#039; auf Werte gesetzt, die Readings und Werte analog zu CUL_HM erzeugen.&lt;br /&gt;
&lt;br /&gt;
Wichtig! Bei der Ausführung von &#039;&#039;&#039;set defaults&#039;&#039;&#039; für das I/O Device wird der Reading-Filter auf den Wert &amp;quot;^(LOW_?BAT|UNREACH)$&amp;quot; gesetzt. Dies hat zur Folge, dass in den Client-Devices nur diese beiden Datenpunkte als Readings gespeichert werden. Daher muss für jedes Client-Device über das lokale Attribut &#039;&#039;ccureadingfilter&#039;&#039; eine Liste der zusätzlich benötigten Datenpunkte definiert werden.&lt;br /&gt;
&lt;br /&gt;
==Synchronisation mit der CCU==&lt;br /&gt;
Das Modul HMCCU bietet Befehle an, um Daten zwischen der CCU und FHEM zu synchronisieren. Der Befehl &#039;&#039;&#039;get devicelist&#039;&#039;&#039; liest alle Geräte aus der CCU. Er sollte immer ausgeführt werden, wenn sich an einer Gerätedefinition in der CCU etwas geändert hat, z.B. Gerät oder Kanal wurde umbenannt, neues Gerät wurde angelernt, Gerät wurde gelöscht. Bei der Definition des I/O Device wird der Befehl automatisch ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Der Befehl &#039;&#039;&#039;get update&#039;&#039;&#039; liest die Datenpunkte aller in FHEM definierten HMCCUDEV und HMCCUCHN Devices aus der CCU und aktualisiert alle Readings aller Client Devices.&lt;br /&gt;
&lt;br /&gt;
==Autocreate von Client Devices==&lt;br /&gt;
HMCCU bietet eine Möglichkeit, um automatisch Client Devices in FHEM für Geräte oder Kanäle in der CCU anzulegen. Dazu wird der Befehl &#039;&#039;&#039;get devicelist&#039;&#039;&#039; mit folgender Syntax aufgerufen:&lt;br /&gt;
&amp;lt;pre&amp;gt;get &amp;lt;io-dev&amp;gt; devicelist create &amp;lt;dev-expr&amp;gt; [Options ...] [&amp;lt;attr&amp;gt;=&amp;lt;value [...]]&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Parameter &#039;&#039;dev-expr&#039;&#039; spezifiziert per regulärem Ausdruck, für welche CCU Geräte oder Kanäle ein Device in FHEM angelegt werden soll. Es ist davon abzuraten, an dieser Stelle &amp;quot;.*&amp;quot; zu verwenden, da so sehr viele (meist unnütze) FHEM Devices angelegt werden.&lt;br /&gt;
Folgende &#039;&#039;Options&#039;&#039; sind möglich:&lt;br /&gt;
*t={chn|dev|all} - Es werden nur Kanäle (chn) oder Geräte (dev) berücksichtigt (ab 3.6).&lt;br /&gt;
*p=&amp;lt;prefix&amp;gt; - Der Text &#039;&#039;prefix&#039;&#039; wird den Namen der neuen FHEM Devices vorangestellt.&lt;br /&gt;
*s=&amp;lt;suffix&amp;gt; - Der Text &#039;&#039;suffix&#039;&#039; wird an die Namen der neuen FHEM Devices angehängt.&lt;br /&gt;
*f=&amp;lt;format&amp;gt; - Mit &#039;&#039;format&#039;&#039; kann ein Template für die FHEM Devicenamen festgelegt werden. In einem Template können folgende Platzhalter verwendet werden: %n = CCU Geräte- oder Kanalname, %d = CCU Gerätename, %a = CCU Geräte- oder Kanaladresse.&lt;br /&gt;
*defattr - Sorgt dafür, dass für die neu definierten FHEM Devices einige Defaultattribute gesetzt werden, sofern für den jeweiligen Gerätetyp vorhanden.&lt;br /&gt;
*duplicates - Erlaubt das Anlegen von doppelten Devices. Wenn diese Option fehlt, werden in FHEM vorhandene Geräte nicht neu angelegt.&lt;br /&gt;
*save - Nach dem Anlegen der Geräte wird die neue FHEM Konfiguration gespeichert.&lt;br /&gt;
An den Befehl kann eine Liste von Attributen angehängt werden, die den neuen FHEM-Devices zugewiesen werden sollen.&lt;br /&gt;
&lt;br /&gt;
Beispiel 1: In FHEM Devices für alle CCU Geräte anlegen, deren Namen mit &amp;quot;HM-KL&amp;quot; beginnt. Alle neuen FHEM Devices beginnen mit &amp;quot;HM_&amp;quot;. Sofern vorhanden werden Default Attribute gesetzt. Die Konfiguration wird gespeichert.&lt;br /&gt;
&amp;lt;pre&amp;gt;get d_ccu devicelist create ^HM-KL.* t=dev f=HM_%n defattr save room=Homematic&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beispiel 2: In FHEM Devices für alle CCU Geräte anlegen, deren Namen mit &amp;quot;HM&amp;quot; oder &amp;quot;Hm&amp;quot; (HmIP-Geräte) beginnt. Alle neuen FHEM Devices haben den Namen wie in der CCU und können dann mit dem Attribut &amp;quot;alias&amp;quot; verständlicher benannt werden. Sofern vorhanden, werden default Attribute gesetzt. Die Konfiguration wird gespeichert. Der Room &amp;quot;CCU_HM&amp;quot; ist angelehnt an &amp;quot;CUL_HM&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;get d_ccu devicelist create ^H[M|m].* t=dev f=%n defattr save room=CCU_HM&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Verwaltung von Default Attributen==&lt;br /&gt;
HMCCU bietet für FHEM Devices vom Typ HMCCUCHN und HMCCUDEV bei bestimmten HomeMatic Gerätetypen Default Attribute an. Diese können in den Client Devices mit dem Befehl &#039;&#039;&#039;set defaults&#039;&#039;&#039; definiert werden. Der Befehl &#039;&#039;&#039;get defaults&#039;&#039;&#039; zeigt die für einen Gerätetyp vorhandenen Attribute an. HMCCU bietet jedem Benutzer die Möglichkeit, zusätzlich zu den in der Datei HMCCUConf.pm mitgelieferten Attributen eigene Vorlagendateien mit Default Attributen zu definieren.&lt;br /&gt;
&lt;br /&gt;
===Anzeigen der Gerätetypen mit Default Attributen===&lt;br /&gt;
Mit dem Befehl &#039;&#039;&#039;get defaults&#039;&#039;&#039; im I/O Device werden alle HomeMatic Gerätetypen angezeigt, für die Default Attribute vorhanden sind. Dabei werden auch benutzerdefinierte Attribute berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
===Default Attribute exportieren und importieren===&lt;br /&gt;
Der Befehl &#039;&#039;&#039;get exportdefaults&#039;&#039;&#039; schreibt die mitgelieferten Default Attribute aus HMCCUConf.pm in eine Vorlagendatei. Diese Datei kann der Benutzer nach seinen Bedürfnissen anpassen und anschließend mit dem Befehl &#039;&#039;&#039;set importdefaults&#039;&#039;&#039; in FHEM importieren. Das Anlegen von eigenen Default Attributen könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
get d_ccu exportdefaults /opt/fhem/hmccu_defattr.txt&lt;br /&gt;
&lt;br /&gt;
... Datei /opt/fhem/hmccu_defattr.txt editieren ...&lt;br /&gt;
&lt;br /&gt;
set d_ccu importdefaults /opt/fhem/hmccu_defattr.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Beim Ausführen des Befehls &#039;&#039;&#039;set defaults&#039;&#039;&#039; in einem Client Device haben die benutzerdefinierten Attribute Priorität.&lt;br /&gt;
&lt;br /&gt;
===Benutzerdefinierte Attribute löschen===&lt;br /&gt;
Mit dem Befehl &#039;&#039;&#039;set cleardefaults&#039;&#039;&#039; werden alle mit &#039;&#039;&#039;set importdefaults&#039;&#039;&#039; importierten Default Attribute gelöscht. Danach sind wieder nur die in HMCCUConf.pm enthaltenen Default Attribute verfügbar.&lt;br /&gt;
&lt;br /&gt;
==Weitere Funktionen des Moduls HMCCU==&lt;br /&gt;
===Lesen und Ändern von CCU Systemvariablen===&lt;br /&gt;
Systemvariablen der CCU können mit den Befehlen &#039;&#039;&#039;get vars&#039;&#039;&#039; und &#039;&#039;&#039;set var&#039;&#039;&#039; gelesen und geändert werden. Der Befehl &#039;&#039;&#039;get vars&#039;&#039;&#039; akzeptiert als Parameter einen regulären Ausdruck. Dadurch können mehrere Systemvariablen auf einmal gelesen werden. Nach dem Auslesen einer Systemvariable wird der Wert in einem Reading im I/O Device gespeichert. &lt;br /&gt;
&lt;br /&gt;
Beispiel: Lesen aller Systemvariablen, die mit A beginnen:&lt;br /&gt;
&amp;lt;pre&amp;gt;get d_ccu vars A.*&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Systemvariablen können in regelmäßigen Abständen gelesen werden. Dazu wird mit dem Attribut ccuGetVars ein Intervall und optional ein regulärer Ausdruck für die zu lesenden Systemvariablen festgelegt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Lesen aller Systemvariablen alle 60 Sekunden. Im zweiten Befehl werden nur Variablen gelesen, die mit &amp;quot;A&amp;quot; beginnen:&lt;br /&gt;
&amp;lt;pre&amp;gt;attr d_ccu ccuGetVars 60&lt;br /&gt;
attr d_ccu ccuGetVars 60:^A&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn eine Systemvariable bereits in der CCU existiert, kann ihr Wert mit dem Befehl &#039;&#039;&#039;set var&#039;&#039;&#039; geändert werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Setzen der Systemvariablen „Temperatur“ auf den Wert 20.5:&lt;br /&gt;
&amp;lt;pre&amp;gt;set d_ccu var Temperatur 20.5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dem Befehl &#039;&#039;&#039;set var&#039;&#039;&#039; kann auch eine neue Systemvariable in der CCU angelegt werden. Dazu wird als erster Parameter vor dem Variablennamen der Typ der neuen Variable angegeben. Mögliche Typen sind &amp;quot;bool&amp;quot;, &amp;quot;list&amp;quot;, &amp;quot;number&amp;quot; oder &amp;quot;text&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Anlegen einer Textvariablen mit dem Namen &amp;quot;Wetter&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;set d_ccu var text Wetter sonnig&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Optional können noch Attribute für eine neue Systemvariable gesetzt werden. Folgende Attribute sind erlaubt:&lt;br /&gt;
&lt;br /&gt;
* unit = Einheit&lt;br /&gt;
* desc = Beschreibung&lt;br /&gt;
* min = Kleinster erlaubter Wert bei numerischen Variablen&lt;br /&gt;
* max = Größter erlaubter Wert bei numerischen Variablen&lt;br /&gt;
* list = Durch Komma getrennte Liste mit zulässigen Werten bei Listen-Variablen&lt;br /&gt;
* valtrue = Angezeigter Wert bei Variablen vom Typ bool, Default = &amp;quot;ist wahr&amp;quot;&lt;br /&gt;
* valfalse = Angezeigter Wert bei Variablen vom Typ bool, Default = &amp;quot;ist falsch&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Beispiel: Anlegen einer numerischen Variablen für Temperaturwerte:&lt;br /&gt;
&amp;lt;pre&amp;gt;set d_ccu var number Temperatur 20.5 unit=Grad desc=Aussentemperatur min=-10.0 max=40.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ausführen von CCU Programmen===&lt;br /&gt;
Ein in der CCU2 hinterlegtes Programm kann mit dem Befehl &#039;&#039;&#039;set execute&#039;&#039;&#039; ausgeführt werden. Einziger Parameter des Befehls ist der Name des Programms. Es spielt keine Rolle, ob das Programm in der CCU aktiv oder inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Programm mit dem Namen &amp;quot;Schalter_Ein&amp;quot; ausführen:&lt;br /&gt;
&amp;lt;pre&amp;gt;set d_ccu execute Schalter_Ein&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Aggregation von Gerätezuständen (ab 3.6)===&lt;br /&gt;
Hinter diesem etwas kryptischen Begriff verbirgt sich die Zusammenfassung von Zuständen von Client-Devices. Anwendungsbeispiele sind:&lt;br /&gt;
* Wieviele und welche Geräte haben einen niedrigen Batteriestand?&lt;br /&gt;
* Wieviele und welche Fenster sind geöffnet?&lt;br /&gt;
Für die Beantwortung dieser Fragen stellt HMCCU einige Befehle und Attribute bereit. Die Ergebnisse werden in Form von Readings im I/O Device bereitgestellt:&lt;br /&gt;
*&#039;&#039;Präfix&#039;&#039;_count = Anzahl der FHEM Devices, die für die Aggregation ausgewertet wurden.&lt;br /&gt;
*&#039;&#039;Präfix&#039;&#039;_list = Liste der FHEM Devices, die der if Bedingung Aggregationsregel entsprechen.&lt;br /&gt;
*&#039;&#039;Präfix&#039;&#039;_match - Anzahl der FHEM Devices, die der if Bedingung der Aggregationsregel entsprechen.&lt;br /&gt;
*&#039;&#039;Präfix&#039;&#039;_state - Ergebnis der Aggregationsregel (if oder else Wert).&lt;br /&gt;
Aggregationen werden automatisch bei Änderung von Readings neu berechnet. Alternativ kann mit dem Befehl &#039;&#039;&#039;get aggregation&#039;&#039;&#039; eine Aggregation explizit durchgeführt werden. Als Parameter wird der Name der Aggregationsregel oder &amp;quot;all&amp;quot; für alle Aggregationen übergeben:&lt;br /&gt;
&amp;lt;pre&amp;gt;get &amp;lt;io-dev&amp;gt; aggregation {all|&amp;lt;name&amp;gt;}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Konfiguration der Aggregationen erfolgt mit Hilfe von Regeln, die über das Attribut &#039;&#039;ccuaggregate&#039;&#039; definiert werden. Dabei werden mehrere Regeln durch ein Semikolon und optional einen Zeilenumbruch getrennt. Eine Aggregationsregel enthält mehrere, durch Komma getrennte Parameter, die das Verhalten einer Aggregation festlegen:&lt;br /&gt;
*&#039;&#039;&#039;name&#039;&#039;&#039;:&amp;lt;Name&amp;gt; - Legt den Namen einer Aggregation fest.&lt;br /&gt;
*&#039;&#039;&#039;filter&#039;&#039;&#039;:{name|alias|group|room|type}=&amp;lt;Incl-Expr&amp;gt;[!&amp;lt;Excl-Expr&amp;gt;] - Legt fest, welche Geräte in die Aggregation einbezogen werden:&lt;br /&gt;
**name: FHEM Device Name&lt;br /&gt;
**alias: FHEM Device Alias&lt;br /&gt;
**group: FHEM Device &#039;&#039;group&#039;&#039; Attribut&lt;br /&gt;
**room: FHEM Device &#039;&#039;room&#039;&#039; Attribut&lt;br /&gt;
**type: HomeMatic Gerätetyp&lt;br /&gt;
*&#039;&#039;&#039;read&#039;&#039;&#039;:&amp;lt;Read-Expr&amp;gt; - Legt fest, welche Readings für die Aggregation verwendet werden (z.B. state oder LOWBAT).&lt;br /&gt;
*&#039;&#039;&#039;if&#039;&#039;&#039;:{any|all}=&amp;lt;Value&amp;gt; - Legt die Bedingung fest, unter der die Aggregationsregel greift:&lt;br /&gt;
**any: Regel greift, wenn das Reading mindestens eins der über &#039;&#039;Filter&#039;&#039; selektierten FHEM Devices den Wert &#039;&#039;Value&#039;&#039; hat.&lt;br /&gt;
**all: Regel greift, wenn die Readings aller der über &#039;&#039;Filter&#039;&#039; selektierten FHEM Devices den Wert &#039;&#039;Value&#039;&#039; haben.&lt;br /&gt;
*&#039;&#039;&#039;else&#039;&#039;&#039;:&amp;lt;Value&amp;gt;&lt;br /&gt;
*&#039;&#039;&#039;prefix&#039;&#039;&#039;:{RULE|&amp;lt;Text&amp;gt;} - Legt das Präfix für die Readings fest, die das Ergebnis einer Aggregation beinhalten wobei &amp;quot;RULE&amp;quot; für den Namen der Aggregationsregel steht.&lt;br /&gt;
*&#039;&#039;&#039;coll&#039;&#039;&#039;:{NAME|&amp;lt;Attribute&amp;gt;}[!&amp;lt;Default&amp;gt;] - Legt fest, welches Attribut der FHEM Devices, die in die Aggregation einbezogen werden, in das _list Reading aufgenommen werden, sofern sie die if Bedingung erfüllen. Dabei entspricht &amp;quot;NAME&amp;quot; dem FHEM-Devicename. Der optionale Parameter Default legt den Inhalt des _list Readings fest, wenn keines der FHEM Devices die if Bedingung erfüllt. Voreingestellt ist &amp;quot;no match&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Aggregation der Batteriezustände aller HomeMatic Geräte in FHEM (Annahme: Alle gehören zum Raum &amp;quot;Homematic&amp;quot;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attr d_ccu ccuaggregate name:battery,filter:room=Homematic,read:(LOWBAT|LOW_BAT),if:any=yes,else:no,prefix=battery_,coll:alias&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Diese Aggregationsregel könnte folgende Readings im I/O Device generieren (Annahme: Batterien von 2 Fenstersensoren leer):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
battery_count: 50&lt;br /&gt;
battery_list: Fenster Bad,Fenster Wohnzimmer&lt;br /&gt;
battery_match: 2&lt;br /&gt;
battery_state: yes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ausführen von HomeMatic Scripts===&lt;br /&gt;
Mit dem Befehl &#039;&#039;&#039;set hmscript&#039;&#039;&#039; kann ein beliebiges HomeMatic Script an die CCU2 zur Ausführung gesendet werden. Wenn das Script zeilenweise Daten im Format &amp;quot;Parameter=Value&amp;quot; zurück gibt, werden diese als Readings mit dem Namen &#039;&#039;Parameter&amp;quot; im I/O Device gespeichert.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Beispiel: Das folgende HomeMatic Script wertet alle CCU2 Systemvariablen aus. Das Ergebnis wird als Readings gespeichert (äquivalent zu Befehl &#039;&#039;&#039;get vars&#039;&#039;&#039;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
object osysvar;&lt;br /&gt;
string ssysvarid;&lt;br /&gt;
foreach (ssysvarid, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs())&lt;br /&gt;
{&lt;br /&gt;
   osysvar = dom.GetObject(ssysvarid);&lt;br /&gt;
   WriteLine (osysvar.Name() # &amp;quot;=&amp;quot; # osysvar.Value());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn das Script auf dem FHEM-Server unter /opt/fhem/sysvars.scr gespeichert wird, kann es wie folgt ausgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;set d_ccu hmscript /opt/fhem/sysvars.scr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HomeMatic Components]]&lt;br /&gt;
[[Kategorie:Interfaces]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=CsrfToken-HowTo&amp;diff=35368</id>
		<title>CsrfToken-HowTo</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=CsrfToken-HowTo&amp;diff=35368"/>
		<updated>2021-03-27T10:26:36Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Webhook sinnvoll eingebaut&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SEITENTITEL:csrfToken-HowTo}}&lt;br /&gt;
==Vorbemerkung==&lt;br /&gt;
FHEM hat mit der Version 5.8 eine Sicherheitsmaßnahme scharfgeschaltet, den csrfToken.&lt;br /&gt;
Dieser Token wird bei jedem Neustart von FHEM neu gebildet.&lt;br /&gt;
&lt;br /&gt;
Dieses Feature erhöht die Sicherheit (siehe Links ganz unten), führt aber dazu, dass man nicht mehr (wie in älteren Anleitungen beschrieben), mit einem statischen http Link Steuerbefehle (auch Webhooks) an das [[FHEMWEB]] senden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Schalte den &amp;quot;Schalter&amp;quot; Office auf on. Das ging früher ohne CsrfToken einfach durch diesen HTML String - egal ob im Browser, in Windows, auf dem Mac, auf der Kommandozeile mit wget usw.&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;http://hostname:8083/fhem?cmd=set%20Office%20on&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Mit CsrfToken müsste diese Zeile so aussehen (Beispiel, der Token ändert sich bei jedem Start von FHEM):&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;http://hostname:8083/fhem?cmd=set%20Office%20on&amp;amp;fwcsrf=csrf_196525024154371&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ist der CsrfToken falsch (weil durch Neustart geändert) erfolgt keine Reaktion Schalters und es gibt eine (ähnliche) Fehlermeldung im FHEMLog:&lt;br /&gt;
  2019.10.24 12:08:13 3: FHEMWEB WEB CSRF error: csrf_104345683644172 ne csrf_148832911104462 for client WEB_192.168.178.20_54197 ...&lt;br /&gt;
&#039;&#039;Diese Fehlermeldung kann selten auch so beim Neustart auftauchen, wenn ein Browser Fenster mit altem Token nach einem &amp;quot;shutdown restart&amp;quot; einfach nur einen Refresh macht.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Soll ein http: Link zum Steuern von FHEM verwendet werden, gibt es folgende Lösungsansätze:&lt;br /&gt;
&lt;br /&gt;
==Codebeispiele==&lt;br /&gt;
===Einzeiler Shell===&lt;br /&gt;
&lt;br /&gt;
Entweder mit curl oder wget &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;curl -s -D - &#039;http://localhost:8083/fhem?XHR=1&#039; | awk &#039;/X-FHEM-csrfToken/{print $2}&#039;&lt;br /&gt;
wget -qO - --server-response &#039;http://localhost:8083/fhem?XHR=1&#039; 2&amp;gt;&amp;amp;1 | awk &#039;/X-FHEM-csrfToken/{print $2}&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
kann man den aktuellen csrfToken aus dem Header extrahieren und muss ihn nur noch an den Aufruf anhängen.&lt;br /&gt;
&lt;br /&gt;
Erste Variante mit curl:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;curl --data &amp;quot;fwcsrf=$(curl -s -D - &#039;http://localhost:8083/fhem?XHR=1&#039; | awk &#039;/X-FHEM-csrfToken/{print $2}&#039;)&amp;quot; http://localhost:8083/fhem?cmd=set%20Office%20on&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oder mit mehr Komfort (eigentlich ein Mehrzeiler): Nur Einmal die Angabe des Hostnamen und den FHEM Befehl normal mit Leerzeichen angeben:&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;h=&#039;Name oder IP:PortNr&#039;; c=&#039;FHEM Befehl&#039;; curl --data &amp;quot;fwcsrf=$(curl -s -D - http://$h/fhem?XHR=1 | awk &#039;/X-FHEM-csrfToken/{print $2}&#039;)&amp;quot; http://$h/fhem?cmd=$(echo $c|sed &#039;s/ /%20/g&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein übersichtlicher Mehrzeiler mit wget. Als Beispiel wird vom localhost:8083 ein &amp;quot;list global&amp;quot; ohne HTML ausgegeben:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;hosturl=&amp;quot;http://localhost:8083&amp;quot;&lt;br /&gt;
cmd=list%20global&lt;br /&gt;
token=$(wget -qO - --server-response &amp;quot;$hosturl/fhem?XHR=1&amp;quot; 2&amp;gt;&amp;amp;1 | awk &#039;/X-FHEM-csrfToken/{print $2}&#039;)&lt;br /&gt;
wget -q -O - &amp;quot;$hosturl/fhem?cmd=$cmd&amp;amp;fwcsrf=$token&amp;amp;XHR=1&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man kann auch noch den token vom cr+lf am Ende befreien:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;curl &amp;quot;http://fhem.example.org:8083/fhem?cmd=set%20Office%20on&amp;amp;XHR=1&amp;amp;fwcsrf=&amp;quot;`curl -s -D - &#039;http://fhem.example.org:8083/fhem?XHR=1&#039; | awk &#039;/X-FHEM-csrfToken/{print $2}&#039; | tr -d &amp;quot;\r\n&amp;quot;`&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Innerhalb FHEM mit Perl===&lt;br /&gt;
FHEM kennt natürlich seinen Token und man hat einfachen Zugriff mit der Variable $FW_CSRF. Diese Varibale enthält nicht den Token an sich, sondern den kompletten String zum Anhängen an eine URL in der Form: &amp;amp;fwcsrf=csrf_387849633005507&lt;br /&gt;
&lt;br /&gt;
Beispiel (funktioniert auch in der FHEM Kommandozeile)&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;{my $button_test = &amp;quot;&amp;lt;a href=&#039;http://localhost:8083/fhem?cmd=set%20Office%20on$FW_CSRF&#039;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl Sub ===&lt;br /&gt;
Innerhalb von Perl geht die Abfrage eines anderen FHEM Servers natürlich auch:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub fhemcl&lt;br /&gt;
{&lt;br /&gt;
   use URI::Escape;&lt;br /&gt;
   use LWP::UserAgent;&lt;br /&gt;
   # if url is empty, localhost and default port is used&lt;br /&gt;
     my $fhemcmd = shift // return &amp;quot;Usage: fhemcl(&#039;fhem cmd&#039;[,&#039;urlToHost&#039;]) - like fhemcl(&#039;set Test2 toggle&#039;,&#039;http://host:8083&#039;)\n&amp;quot;;&lt;br /&gt;
     my $hosturl = shift || &#039;http://localhost:8083&#039;;&lt;br /&gt;
     my $token;&lt;br /&gt;
   # get token &lt;br /&gt;
     my $ua = new LWP::UserAgent;&lt;br /&gt;
     my $url = &amp;quot;$hosturl/fhem?XHR=1/&amp;quot;;&lt;br /&gt;
     my $resp = $ua-&amp;gt;get($url);&lt;br /&gt;
        $token = $resp-&amp;gt;header(&#039;X-FHEM-CsrfToken&#039;);&lt;br /&gt;
   # url encode the cmd&lt;br /&gt;
     $fhemcmd = uri_escape($fhemcmd);&lt;br /&gt;
     $url = &amp;quot;$hosturl/fhem?cmd=$fhemcmd&amp;amp;fwcsrf=$token&amp;amp;XHR=1&amp;quot;;&lt;br /&gt;
     $resp = $ua-&amp;gt;get($url)-&amp;gt;content;&lt;br /&gt;
   # cut the last character: the additional newline&lt;br /&gt;
     return substr $resp,0,-1&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Raw Import in der Shell===&lt;br /&gt;
Will man ganze Definitionsblöcke von der System Kommandozeile importieren, kann man dieses Script verwenden. Im übergebenen Dateinamen sind Zeilenweise die FHEM Befehle gespeichert. Bei Bedarf kann man auch einen anderen Hostnamen und ein anderes Port angeben. Der Token wird zu Beginn ermittelt. Die Leerzeichen werden für HTTP durch %20 ersetzt.&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# fhemraw Import analog Raw Definition&lt;br /&gt;
if [ $# -eq 0 ] ; then&lt;br /&gt;
     echo fhemraw bitte so verwenden&lt;br /&gt;
     echo fhemraw &amp;lt;dateiName&amp;gt; [&amp;lt;hostName&amp;gt;] [&amp;lt;portNummer&amp;gt;]&lt;br /&gt;
     exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ -z $2 ] ; then&lt;br /&gt;
     fhemhost=localhost&lt;br /&gt;
   else&lt;br /&gt;
     fhemhost=$2&lt;br /&gt;
fi&lt;br /&gt;
if [ -z $3 ] ; then&lt;br /&gt;
     fhemhost=$fhemhost:8083&lt;br /&gt;
   else&lt;br /&gt;
     fhemhost=$fhemhost:$3&lt;br /&gt;
fi&lt;br /&gt;
token=$(curl -s -D - &amp;quot;http://$fhemhost/fhem?XHR=1&amp;quot; | awk &#039;/X-FHEM-csrfToken/{print $2}&#039;)&lt;br /&gt;
&lt;br /&gt;
while read line&lt;br /&gt;
do&lt;br /&gt;
    curl --data &amp;quot;fwcsrf=$token&amp;quot; http://$fhemhost/fhem?cmd=$(echo $line|sed &#039;s/ /%20/g&#039;)&lt;br /&gt;
done &amp;lt; $1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Python===&lt;br /&gt;
Falls mal jemand aus python (hier für python 2.7) heraus fhem ansteuern möchte&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
 import sys&lt;br /&gt;
 import urllib2&lt;br /&gt;
 import urllib&lt;br /&gt;
 import ssl&lt;br /&gt;
 import urlparse&lt;br /&gt;
 BASEURL = &#039;https://user:password@server_ip:8083/fhem?&#039;&lt;br /&gt;
 url = BASEURL + &#039;cmd=set+licht+on&#039;&lt;br /&gt;
 def get_token(url):&lt;br /&gt;
     nurl = urlparse.urlsplit(url)&lt;br /&gt;
     username = nurl.username&lt;br /&gt;
     password = nurl.password&lt;br /&gt;
     url = url.replace(username + &#039;:&#039; + password + &#039;@&#039;, &#039;&#039;)&lt;br /&gt;
     url = url.replace(&amp;quot; &amp;quot;, &amp;quot;%20&amp;quot;)&lt;br /&gt;
     ssl._create_default_https_context = ssl._create_unverified_context&lt;br /&gt;
     p = urllib2.HTTPPasswordMgrWithDefaultRealm()&lt;br /&gt;
     p.add_password(None, url, username, password)&lt;br /&gt;
     handler = urllib2.HTTPBasicAuthHandler(p)&lt;br /&gt;
     opener = urllib2.build_opener(handler)&lt;br /&gt;
     urllib2.install_opener(opener)&lt;br /&gt;
     try:&lt;br /&gt;
         uu = urllib2.urlopen(&lt;br /&gt;
             url=url,&lt;br /&gt;
             data=None,&lt;br /&gt;
             timeout=10&lt;br /&gt;
         )&lt;br /&gt;
         token = uu.read()&lt;br /&gt;
         token = token[token.find(&#039;csrf_&#039;):]&lt;br /&gt;
         token = token[:token.find(&amp;quot;\&#039;&amp;quot;)]&lt;br /&gt;
         return token&lt;br /&gt;
     except urllib2.URLError, urllib2.URLError.reason:&lt;br /&gt;
         print(&#039;URLError: %s&#039; % urllib2.URLError.reason)&lt;br /&gt;
         return False&lt;br /&gt;
  &lt;br /&gt;
 def fire_command(url):&lt;br /&gt;
     # type: (object) -&amp;gt; object&lt;br /&gt;
     if &amp;quot;@&amp;quot; in url:&lt;br /&gt;
         token = get_token(BASEURL)&lt;br /&gt;
         data = {&#039;fwcsrf&#039;: token}&lt;br /&gt;
         data = urllib.urlencode(data)&lt;br /&gt;
         nurl = urlparse.urlsplit(url)&lt;br /&gt;
         username = nurl.username&lt;br /&gt;
         password = nurl.password&lt;br /&gt;
         url = url.replace(username + &#039;:&#039; + password + &#039;@&#039;, &#039;&#039;)&lt;br /&gt;
         url = url.replace(&amp;quot; &amp;quot;, &amp;quot;%20&amp;quot;)&lt;br /&gt;
         ssl._create_default_https_context = ssl._create_unverified_context&lt;br /&gt;
         p = urllib2.HTTPPasswordMgrWithDefaultRealm()&lt;br /&gt;
         p.add_password(None, url, username, password)&lt;br /&gt;
         handler = urllib2.HTTPBasicAuthHandler(p)&lt;br /&gt;
         opener = urllib2.build_opener(handler)&lt;br /&gt;
         urllib2.install_opener(opener)&lt;br /&gt;
         try:&lt;br /&gt;
             urllib2.urlopen(&lt;br /&gt;
                 url=url,&lt;br /&gt;
                 data=data,&lt;br /&gt;
                 timeout=10&lt;br /&gt;
             )&lt;br /&gt;
         except urllib2.URLError, urllib2.URLError.reason:&lt;br /&gt;
             print(&#039;URLError: %s&#039; % urllib2.URLError.reason)&lt;br /&gt;
             return False&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Alternative Konfiguration==&lt;br /&gt;
===API Web===&lt;br /&gt;
Falls man ohne den Token arbeiten will, könnte man ein eigenes API Web erstellen und den Zugriff darauf beschränken. In vorhandenen Scripten / Applikationen müsste dann lediglich der Port geändert werden. &lt;br /&gt;
  &lt;br /&gt;
  define WEBapi FHEMWEB 8088 global&lt;br /&gt;
  attr WEBapi csrfToken none&lt;br /&gt;
  attr WEBapi allowfrom 192.168.178.83|127.0.0.1&lt;br /&gt;
&lt;br /&gt;
Im Forum ist beschrieben wie man die Gestaltung des regEx für die IP Adresse machen kann ({{Link2Forum|Topic=23994}}).&lt;br /&gt;
Einen regEx Builder für IP-Ranges findet man unter &lt;br /&gt;
[http://www.analyticsmarket.com/freetools/ipregex]&lt;br /&gt;
&lt;br /&gt;
===csrfToken festlegen===&lt;br /&gt;
Dies kann man tun, falls die dynamische Abfrage zur Laufzeit des Tokens nicht möglich ist. &lt;br /&gt;
:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;attr WEB.* csrfToken &amp;lt;beliebige Folge aus Zeichen und Zahlen&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit können feste URLs verwendet werden:&lt;br /&gt;
:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://localhost:8083/fhem?cmd=set%20Office%20on&amp;amp;fwcsrf=&amp;lt;fester token&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===csrfToken abschalten===&lt;br /&gt;
Dies sollte man als erste Hilfe tun, aber unbedingt darüber nachdenken wie man die Applikation umstellt.&lt;br /&gt;
:&amp;lt;code&amp;gt;attr WEB.* csrfToken none&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Featurelevel===&lt;br /&gt;
Eine weitere temporäre Notfallmaßnahme wäre den Featurelevel nach dem Update einfach wieder zurückzudrehen&lt;br /&gt;
:&amp;lt;code&amp;gt;attr global featurelevel 5.7&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Automatisch das korrekte Token in Weblink einbinden: {{Link2Forum|Topic=67543|Message=590584}}&lt;br /&gt;
* [https://de.wikipedia.org/wiki/Cross-Site-Request-Forgery Wikipedia - Cross Site Request Forgery (csrf)]&lt;br /&gt;
* [http://heinz-otto.blogspot.de/2017/03/csrf-token-und-fhem.html Blog-Beitrag zu csrf-Token und FHEM]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HOWTOS]]&lt;br /&gt;
[[Kategorie:Glossary]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35135</id>
		<title>DevelopmentModuleAPI</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleAPI&amp;diff=35135"/>
		<updated>2021-03-02T17:55:32Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Fehlende Parameter für parseParams() dokumentiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Randnotiz|RNTyp=r|RNText=Bitte beachten: Diese Auflistung von Funktionen wird nicht aktiv durch alle Entwickler gepflegt. Es kann daher keine Garantie auf Vollständigkeit und Korrektheit gegeben werden. Letztendlich entscheidend ist immer der Perl-Code, Unstimmigkeiten sollten im [https://forum.fhem.de/index.php/board,80.0.html FHEM-Forum] angemerkt werden!&lt;br /&gt;
&amp;lt;hr /&amp;gt;&lt;br /&gt;
Please note: This list of functions is not officially maintained by all developers. So there is no guarantee for completeness and correctness. In the end it is always the Perl code itself that is relevant; please report errors and omissions in the [https://forum.fhem.de/index.php/board,80.0.html FHEM forum]!&lt;br /&gt;
}}&lt;br /&gt;
Dieses Seite soll eine Beschreibung der für Moduleentwickler verfügbaren Funktionen enthalten, um für Modulentwickler &lt;br /&gt;
* Wiederverwendbare Routinen leichter identifizieren zu können&lt;br /&gt;
* Durch Wiederverwendung mehr Einheitlichkeit zu erzeugen&lt;br /&gt;
* Aufwand zu verringern&lt;br /&gt;
* Bei Änderungen auch betroffene Module leichter identifizieren zu können&lt;br /&gt;
&lt;br /&gt;
Natürlich hat diese Seite keinen Anspruch auf Vollständigkeit und jeder ist aufgefordert mitzuarbeiten, sobald er beim Stöbern über eine Funktion stolpert, die auch andere interessieren könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Befehlsausführung ==&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = AnalyzeCommand($client_hash, $cmd);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzeCommand() ermöglicht das Parsen und die Ausführung eines einzelnen FHEM-Befehls.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieses Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition das Kommando &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;). Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein einzelnes Kommando, welches ausgeführt werden soll (ACHTUNG: keine Kommando-Ketten!!!).&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{Log3(undef, 1, &amp;quot;Hallo&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen des Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzeCommandChain ===&lt;br /&gt;
AnalyzeCommandChain() ermöglicht die Ausführung von FHEM-Befehlsketten. Dabei werden mehrere FHEM-Kommandos durch ein Semikolon getrennt und nacheinander mittels AnalyzeCommand() ausgeführt.&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzeCommandChain ($client_hash, $cmds)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Kommandokette, welche ausgeführt werden soll, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;define dummy1 dummy; list dummy1; {Log(3,&amp;quot;dummy created&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AnalyzePerlCommand ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$errors = AnalyzePerlCommand ($client_hash, $cmds);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AnalyzePerlCommand() ermöglicht die Ausführung von Perl-Kommandos/Routinen. Sofern &amp;quot;$client_hash&amp;quot; angegeben wurde, wird die  Authorisierung geprüft (man kann mit allowed die Ausfuehrung von perl untersagen). &lt;br /&gt;
Mehrere Kommandos sind innerhalb von &amp;quot;$cmds&amp;quot; durch Semikolon zu trennen. &lt;br /&gt;
&lt;br /&gt;
Sollten Warnung bei der Ausführung der Perl-Kommandos auftreten, werden sie im FHEM-Logfile mit verbose-Level &amp;quot;1&amp;quot; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sind [[#EvalSpecials|EvalSpecials()]] definiert, können diese Definitionen innerhalb des übergebenen Perl-Codes verwendet werden.&lt;br /&gt;
Ebenfalls werden die Variablen $we (siehe holiday2we), $sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst (siehe Perl localtime) sowie $hms (Zeit im sprintf-Format &amp;quot;hh:mm:ss&amp;quot;) generiert und können somit im auszuführenden Code verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Definition-Hash, welcher für die Ausführung dieser Kommandos verantwortlich ist. Dies dient zur Prüfung, ob diese Definition die Kommandos &amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt; ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;).Der Definition-Hash muss in &amp;lt;code&amp;gt;SNAME&amp;lt;/code&amp;gt; den zum Attribut &amp;lt;code&amp;gt;validFor&amp;lt;/code&amp;gt; (im zugehörigen allowed-Device) passenden Devicenamen tragen, damit die Prüfung durchgeführt wird. Wenn anstatt eines Definitions-Hashes der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; übergeben wird, erfolgt keine Prüfung.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmds&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Perl-Kommando(s), welche ausgeführt werden sollen, durch &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt; getrennt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt; my $ignore; if($we) {$ignore=1} &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$errors&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehlermeldungen, die beim Ausführen der Kommandos aufgetreten sind. Wenn keine Fehlermeldungen aufgetreten sind, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== EvalSpecials ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$final_cmd = EvalSpecials($cmd, %specials);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
EvalSpecials() ermöglicht die Ersetzung von Platzhaltern in FHEM-Befehlen, welche durch AnalyzeCommandChain() zur Ausführung gebracht werden sollen. Dabei werden alle Schlüssel von &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; gesucht und durch die entsprechenden Werte aus &amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt; ersetzt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion hat je nach gewähltem Featurelevel (globales Attribut &amp;lt;code&amp;gt;featurelevel&amp;lt;/code&amp;gt;) unterschiedliches Verhalten um die Kompatibilität mit früheren FHEM-Versionen und deren Konfiguration zu wahren.&lt;br /&gt;
&lt;br /&gt;
In jedem Falle muss der zurückgegebene String mit AnalyzeCommandChain() zur Ausführung gebracht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine gültige FHEM-Kommando-Kette welche mit etwaigen Platzhaltern versehen ist, die ersetzt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;set $NAME power on; {Log(3, &amp;quot;power on $NAME for $ADDRESS&amp;quot;)}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;%specials&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash, welcher als Schlüssel die zu ersetzenden Platzhalter-Namen den zu ersetzenden Werten zuordnet. Jeder Schlüssel ist aus historischen Gründen mit einem Prozentzeichen zu beginnen. Die Platzhalter müssen zusammenhängend sein und dürfen nur aus Zahlen, Buchstaben und Unterstrichen (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) bestehen. Generell sollten die Schlüssel aber nur aus Großbuchstaben bestehen.&lt;br /&gt;
&lt;br /&gt;
Bspw: &amp;lt;code&amp;gt;(&amp;quot;%NAME&amp;quot; =&amp;gt; &amp;quot;Definition_A&amp;quot;, &amp;quot;%ADDRESS&amp;quot; =&amp;gt; &amp;quot;192.168.0.2&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$final_cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Das fertige Kommando, welches so direkt an AnalyzeCommandChain() übergeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Ab Featurelevel 5.7 sind die Platzhalter in diesem String nicht ersetzt. Die Ersetzung wird in diesem Fall in AnalyzeCommandChain() vorgenommen, wo die einzelnen Platzhalter ersetzt werden. Die Funktion EvalSpecials() speichert in diesem Falle nur den Hash im Hintergrund, die eigentliche Ersetzung wird dann durch AnalyzeCommandChain() und deren untergeordneten Funktionen übernommen.&lt;br /&gt;
&lt;br /&gt;
In Featurelevel 5.6 und vorher wird ein Suchen/Ersetzen der Platzhalter in EvalSpecials() selbst vorgenommen. Hierbei ist der zurückgegebene String das finale Kommando, welches keine Platzhalter mehr beinhaltet. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== parseParams ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;my($a, $h) = parseParams($cmd);&lt;br /&gt;
my($a, $h) = parseParams($cmd, $separator, $joiner, $keyvalueseparator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parseParams() ermöglicht das Parsen von Kommandozeilenargumenten und lässt sich z.B. für die Parameter von define ([[DevelopmentModuleIntro#X_Define|DefineFn]]), get ([[DevelopmentModuleIntro#X_Get|GetFn]]) und set ([[DevelopmentModuleIntro#X_Set|SetFn]]) verwenden. Beim Parsen werden erkannt:&lt;br /&gt;
* einfache, durch den Separator getrennte, Zeichenfolgen&lt;br /&gt;
* benannte Parameter der Form &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Werte können in einfache (&amp;lt;code&amp;gt;&#039;&amp;lt;/code&amp;gt;) oder doppelte (&amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;) Anführungszeichen eingeschlossen sein, um so den jeweiligen Separator zu enthalten&lt;br /&gt;
** Ein solches Pärchen aus gleichen Anführungszeichen an Anfang und Ende eines Wertes wird beim Parsen entfernt.&lt;br /&gt;
* in &amp;lt;code&amp;gt;{...}&amp;lt;/code&amp;gt; eingeschlossener Perlcode. Hier wird nach der ersten öffnenden bis zur zugehörigen schliessenden Klammer gesucht. D.h. bis die gleiche Anzahl öffnender und schliessender Klammern erreicht ist. &lt;br /&gt;
&lt;br /&gt;
In der Modul &amp;lt;code&amp;gt;X_Initialize&amp;lt;/code&amp;gt; Routine lässt sich mit &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; festlegen, dass parseParams für die define, get und set Argumente automatisch aufgerufen und das Ergebnis an die DefFn, GetFn und SetFn übergeben wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Argumente des Kommandos als String oder als Array-Referenz. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$separator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Separator, an dem die Parameterzeile in einzelne Parameter gesplittet werden soll. Dieser Parameter wird nur beachtet, wenn die Argumente als Zeichenkette übergeben werden. &lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039; &#039; &#039;&#039;(Leerzeichen)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$joiner&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;&amp;lt;code&amp;gt;$keyvalueseparator&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|Trennzeichen, das &amp;lt;name&amp;gt;- von &amp;lt;wert&amp;gt;-Paaren trennt, Standardwert ist &#039;=&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf ein Array, das alle nicht benannten Parameter in der Reihenfolge ihres Vorkommens enthält.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$h&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Eine Referenz auf einen Hash, der die Werte aller benannten Parameter mit ihrem Namen als Key enthält. (Achtung: Ein Hash ist nicht sortiert!)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Beispiel: Die Zeile &lt;br /&gt;
:&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; test1 test2=abc test3 &amp;quot;test4 test4&amp;quot; test5=&amp;quot;test5 test5&amp;quot; test6=&#039;test6=test6&#039; test7= test8=&amp;quot;&#039;&amp;quot; test9=&#039;&amp;quot;&#039; {my $x = &amp;quot;abc&amp;quot;} test10={ { my $abc =&amp;quot;xyz&amp;quot; } }&amp;lt;/code&amp;gt;&lt;br /&gt;
wird in die folgenden Elemente geparst:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# Die nicht benannten Parameter:&lt;br /&gt;
$a = [&lt;br /&gt;
          &#039;set&#039;,&lt;br /&gt;
          &#039;&amp;lt;name&amp;gt;&#039;,&lt;br /&gt;
          &#039;test1&#039;,&lt;br /&gt;
          &#039;test3&#039;,&lt;br /&gt;
          &#039;test4 test4&#039;,&lt;br /&gt;
          &#039;{my $x = &amp;quot;abc&amp;quot;}&#039;&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
# Die benannten Parameter:&lt;br /&gt;
$h = {&lt;br /&gt;
          &#039;test10&#039; =&amp;gt; &#039;{ { my $abc =&amp;quot;xyz&amp;quot; } }&#039;,&lt;br /&gt;
          &#039;test5&#039; =&amp;gt; &#039;test5 test5&#039;,&lt;br /&gt;
          &#039;test8&#039; =&amp;gt; &#039;\&#039;&#039;,&lt;br /&gt;
          &#039;test2&#039; =&amp;gt; &#039;abc&#039;,&lt;br /&gt;
          &#039;test7&#039; =&amp;gt; &#039;&#039;,&lt;br /&gt;
          &#039;test9&#039; =&amp;gt; &#039;&amp;quot;&#039;,&lt;br /&gt;
          &#039;test6&#039; =&amp;gt; &#039;test6=test6&#039;&lt;br /&gt;
        };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== asyncOutput ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;asyncOutput($client_hash, $message);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion asyncOutput() kann man an einen bestimmten Client (FHEMWEB oder telnet) gezielt Daten übermitteln, die auf diesem Client angezeigt werden sollen. Damit können Kommandos via FHEMWEB oder Telnet gestartet werden und das Ergebnis zu einem späteren Zeitpunkt zurückgegeben werden. Ebenso können so Daten angefordert werden und erst zum Zeitpunkt des Eintreffens via asyncOutput() an den entsprechenden Client weitergeleitet werden.&lt;br /&gt;
&lt;br /&gt;
Um diese Funktion nutzen zu können, muss das Modul, über das eine Client-Verbindung besteht, eine [[DevelopmentModuleIntro#X_AsyncOutputFn|AsyncOutputFn]] bereitstellen. Dies wird aktuell nur in [[FHEMWEB]] und telnet unterstützt. Man kann die Unterstützung für eine asynchrone Datenübermittlung vorab mittels einer if-Abfrage auf&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; prüfen, da es durchaus passieren kann, dass unter bestimmten Umständen keine asynchrone Übertragung möglich ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Client-Instanz (telnet- oder FHEMWEB-Instanz), auf das die Ausgabe erfolgen soll. Dieser Client-Hash wird beim Aufruf der [[DevelopmentModuleIntro#X_Set|SetFn]] und [[DevelopmentModuleIntro#X_Get|GetFn]] unter &amp;lt;code&amp;gt;$hash-&amp;gt;{CL}&amp;lt;/code&amp;gt; bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Daten als Zeichenkette, welche ausgegeben werden sollen. &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensions ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = SetExtensions($hash, $usage_list, @set_args);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion SetExtensions() wird durch das Hilfsmodul SetExtensions.pm bereitgestellt und implementiert weiterführende Set-Befehle basierend auf den Grundbefehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;. Sie wird ausschließlich im Rahmen der Modulprogrammierung in der [[DevelopmentModuleIntro#X_Set|Set]]-Funktion verwendet.&lt;br /&gt;
&lt;br /&gt;
Ein Implementierungsbeispiel gibt es im Wiki-Artikel zur [[DevelopmentModuleIntro#X_Set|Set]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Hash-Referenz der Gerätedefinition, für die gerade die [[DevelopmentModuleIntro#X_Set|Set]]-Funktion ausgeführt wird.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$usage_list&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Die Auflistung aller möglichen Kommandos als Zeichenkette, welche innerhalb der Set-Funktion unterstützt werden. Es handelt sich hierbei nur reinweg um die Auflistung der Kommandos ohne das Präfix &amp;lt;code&amp;gt;unknown command &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;[...]&#039;&#039;&amp;lt;/font&amp;gt; choose one of&amp;lt;/code&amp;gt;. Diese Liste muss mind. die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; enthalten, damit SetExtensions() zusätzliche Set-Befehle anbieten kann. Es können hierbei FHEMWEB-spezifische Widget-Optionen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on off statusRequest&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;on:noArg off:noArg input:av1,av2,av3 volume&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@set_args&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039; &lt;br /&gt;
|| Sämtliche Argumente, welche an die Set-Funktion übergeben wurden (ausser &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;). Dieses Array entspricht einem Array aus den Parametern &amp;lt;code&amp;gt;($name, $cmd, @args)&amp;lt;/code&amp;gt; aus dem [[DevelopmentModuleIntro#X_Set|Artikel zur Set-Funktion]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Fehler- bzw. Usage-Meldung, die beim Ausführen von SetExtensions() aufgetreten ist. Diese Rückmeldung muss direkt als Rückgabewert der Set-Funktion verwendet werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[DevelopmentModuleAPI#SetExtensionsCancel|SetExtensionsCancel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Time / Timestamp ==&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTimeRFC1123===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestampGMT = FmtDateTimeRFC1123($timestamp);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Gibt den übergebenen UNIX-Timestamp (Sekunden seit EPOCH-Beginn) formatiert nach RFC 1123 zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestampGMT &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel GMT (Greenwich Mean Time) wie er in RFC 1123 beschrieben wird. Diese werden zum Beispiel bei http verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Sat, 05 Mar 2016 18:17:48 GMT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FmtDateTime===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = FmtDateTime($time);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen UNIX-Timestamp (Sekunden seit Beginn der UNIX-Epoche: 01.01.1970 00:00:00 UTC) in eine formatierte Angabe in der lokalen Zeitzone um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Zeitangabe wie sie von der &amp;lt;code&amp;gt;time()&amp;lt;/code&amp;gt; Funktion zurückgegeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TimeNow ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = TimeNow();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion TimeNow() gibt die aktuelle lokale Zeit als formatierte Zeichenkette zurück. Diese Funktion hat keine Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel der aktuellen Uhrzeit in lokaler Zeitzone im Format&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzt die Funktion &amp;lt;code&amp;gt;FmtDateTime()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeGm===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeGm($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt als Greenwich Mean Time (GMT) basierend auf den einzelnen Datumsangaben, wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;gmtime()&amp;lt;/code&amp;gt; erzeugt wird, in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fhemTimeLocal===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$timestamp = fhemTimeLocal($sec, $min, $hour, $mday, $month, $year);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wandelt einen Zeitpunkt in lokaler Zeit basierend auf den einzelnen Datumsangaben wie er bspw. durch die Perl-Funktion &amp;lt;code&amp;gt;localtime()&amp;lt;/code&amp;gt; erzeugt wird in einen UNIX-Timestamp um.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$sec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Sekunden-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$min&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Minuten-Komponente als Ganzzahl zwischen 0 und 59.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hour&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Stunden-Komponente als Ganzzahl zwischen 0 und 23.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$mday&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Tag-Komponente als Ganzzahl zwischen 1 und 31.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$month&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Monats-Komponente als Ganzzahl zwischen 0 und 11. Hier erfolgt eine andere Zuordnung. Der Januar entspricht der 0, Februar der 1, usw. Der Dezember entspricht dem Wert 11.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$year&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Jahres-Komponente. Das Jahr wird dabei nicht als komplette Jahreszahl angegeben, sondern als Differenz seit dem Jahr 1900. Das Jahr 2016 entspricht demnach dem Wert 116.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp &amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|| Zeitstempel als UNIX-Timestamp (Sekunden seit EPOCH-Beginn) &amp;lt;br&amp;gt;&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;1457201868&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Readings / Events ==&lt;br /&gt;
&lt;br /&gt;
=== readingsBeginUpdate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion readingsBeginUpdate() bereitet die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; auf ein Update von Readings vor. Dies betrifft insbesondere das Setzen von Umgebungsvariablen sowie dem aktuellen Zeitstempel als Änderungszeitpunkt. Der Aufruf dieser Funktion ist notwendig um eigentliche Updates mit der Funktion readingsBulkUpdate() auf der gewünschten Definition durchführen zu können. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdate($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdate() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: [[event-on-change-reading]], [[event-on-update-reading]], [[event-min-interval]], ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsBulkUpdateIfChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value);&lt;br /&gt;
$rv = readingsBulkUpdateIfChanged($hash, $reading, $value, $changed);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsBulkUpdateIfChanged() führt ein Update eines einzelnen Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; durch, sofern sich der neue Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gegenüber dem vorherigen Wert verändert. Dabei wird das Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; auf den Wert &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; gesetzt. Bevor diese Funktion benutzt werden kann, muss readingsBeginUpdate() zuvor aufgerufen werden, ansonsten werden keine Updates durchgeführt. Nur, sobald sich der Wert des Readings verändert, wird die Funktion readingsBulkUpdate() ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet werden sollen &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$changed&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Flag, ob ein Event für dieses Update erzeugt werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Oder ob definitiv kein Event erzeugt werden soll (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;). Wenn nicht gesetzt, wird aufgrund entsprechender Attribute in der Definition von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; entschieden, ob ein Event zu erzeugen ist, oder nicht (Attribute: event-on-change-reading, event-on-update-reading, event-min-interval, ...)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde. Sofern der alte Wert dem neuen Wert entspricht, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsEndUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsEndUpdate($hash, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsEndUpdate() beendet den Bulk-Update Prozess durch die Funktionen readingsBeginUpdate() &amp;amp; readingsBulkUpdate() und triggert optional die entsprechenden Events sämtlicher erzeugter Readings für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;. Desweiteren werden nachgelagerte Tasks wie bspw. die Erzeugung von User-Readings (Attribut: &amp;lt;code&amp;gt;userReadings&amp;lt;/code&amp;gt;), sowie die Erzeugung des STATE aufgrund des Attributs &amp;lt;code&amp;gt;stateFormat&amp;lt;/code&amp;gt; durchgeführt. Sofern &amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt; gesetzt ist, werden alle anstehenden Events nach Abschluss getriggert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo Readings geupdatet wurden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob entsprechende Events der einzelnen Readings getriggert werden sollen (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden keine Events für alle Readings die seit dem Aufruf von readingsBeginUpdate() mittels readingsBulkUpdate() gesetzt wurden, erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsSingleUpdate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$rv = readingsSingleUpdate($hash, $reading, $value, $do_trigger);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsSingleUpdate() führt ein einzelnes Reading-Update mithilfe der Funktionen readingsBeginUpdate(), readingsBulkUpdate() und readingsEndUpdate() durch. Es entspricht dabei einem Aufruf aller 3 Funktionen nacheinander mit den entsprechenden einzelnen Parametern in den jeweiligen Funktionen.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches geupdatet werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Wert, welchen das Reading annehmen soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$do_trigger&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Flag, ob evtl. ein Event für das Reading getriggert werden soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, Event ist abhängig von den Attributen: event-on-change-reading, event-on-update-reading, event-min-interval, ...). Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird kein Event erzeugt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$rv&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette bestehend aus Reading und Wert getrennt durch einen Doppelpunkt, welcher anzeigt, auf welchen Wert das Reading tatsächlich gesetzt wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== readingsDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $reading);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion readingsDelete() löscht das Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; aus der Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, wo das Reading gelöscht werden soll&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name des Readings, welches gelöscht werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DoTrigger ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = DoTrigger($name, $new_state);&lt;br /&gt;
$ret = DoTrigger($name, $new_state, $no_replace);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion DoTrigger() triggert alle angesammelten Events in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; sowie zusätzlich das Event &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und führt alle verarbeitenden Aktionen in allen Empfängern zu diesem Event aus. Wenn in &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; keine zu bearbeitenden Änderungen enthalten sind, wird lediglich &amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt; getriggert (sofern gesetzt).&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird implizit in der Funktion readingsEndUpdate() aufgerufen und muss daher nicht nochmal aufgerufen werden. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Name der Definition deren Events durchgeführt werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$new_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Das Event welches zusätzlich zu bereits anstehenden Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; getriggert werden soll. Wenn dieser Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; ist, werden nur alle Events aus &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; bearbeitet, sofern &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; gefüllt ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_replace&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Optionales Flag, welches die Ersetzung von Events durch das Attribut &amp;lt;code&amp;gt;eventMap&amp;lt;/code&amp;gt; verhindert (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeichenkette welche alle Return-Werte aller aufgerufenen Notify-Funktionen beinhaltet, sofern diese einen Fehler melden. Diese Meldung wird parallel im FHEM-Logfile ausgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== deviceEvents ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$events = deviceEvents($hash, $with_state);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion deviceEvents() gibt alle anstehenden Events für die Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als Array-Referenz zurück. Diese Funktion ist bei der Modulentwicklung primär zur Nutzung in der [[DevelopmentModuleIntro#X_Notify|NotifyFn]] vorgesehen, um die anstehenden Events zu ermitteln. &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, deren anstehende Events zurückgegeben werden sollen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$with_state&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Flag, ob das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; mit dem Readingnamen in der zurückgegebenen Event-Liste erscheinen soll (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;) oder nur der Wert ohne dem vorangestellten Readingnamen &amp;quot;&amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt;&amp;quot; (Wert: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;) in der Event-Liste angezeigt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$events&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Array-Referenz, welche alle anstehenden Events als Liste bereitstellt. Sofern keine Events anstehen, ist der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 0&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bsp. (mit &amp;lt;code&amp;gt;$with_state = 1&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
[ &lt;br /&gt;
    &amp;quot;humidity: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;state: T: 10.5 H: 84&amp;quot;,&lt;br /&gt;
    &amp;quot;temperature: 10.5&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== notifyRegexpChanged ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
notifyRegexpChanged($hash, $event_regexp);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion notifyRegexpChanged() setzt für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; einen passenden Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf dem regulären Ausdruck &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;, welcher üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] als Argument übergeben wird. Dadurch wird die [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] nur für Events der entsprechenden Gerätedefinition aufgerufen. &lt;br /&gt;
&lt;br /&gt;
Je nach dem, wie &amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt; formuliert ist, setzt notifyRegexpChanged() einen Eintrag in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;. Es kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Funktion kann nur verwendet werden, wenn &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; auf &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;lt;code&amp;gt;&amp;amp;lt;Definitionsnamen&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt;&#039;&#039;&#039; matcht (Event Regexp-Syntax aus [[notify]]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Hash-Referenz der Definition, für welche eine neue Event-Regexp gesetzt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$event_regexp&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Regexp, welche für &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt wurde (i.d.R via [[DevelopmentModuleIntro#X_Define|Define-Funktion]])&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodReadingName() prüft, ob der Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Readingname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bindestrich &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
* Schrägstrich &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Readingname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Readingname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Readingname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Readingname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Readingname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeReadingName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeReadingName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeReadingName() entfernt aus dem übergebenen Readingname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Readingname in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Readingname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== zweistufige Modulkommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== AssignIoPort ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
AssignIoPort($hash);&lt;br /&gt;
AssignIoPort($hash, $proposedName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion AssignIoPort() sucht nach einem passenden IO-Gerät (physikalische Definition) nach folgender Vorgehensweise:&lt;br /&gt;
&lt;br /&gt;
# Sofern &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; angegeben ist und der Gerätename existiert und nicht disabled ist (Attribute &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; auf 1 gesetzt), wird &amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt; als IO-Gerät ausgewählt. &lt;br /&gt;
# Sofern der Nutzer über das Attribut &amp;lt;code&amp;gt;IODev&amp;lt;/code&amp;gt; einen Gerätenamen konfiguriert hat, wird dieser als IO-Gerät ausgewählt.&lt;br /&gt;
# Es werden alle Module geprüft, die entsprechende Nachrichten des Modultyps von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; als IO-Gerät annehmen (via [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]]). Die passende Definition, welche als letztes definiert wurde, wird als IO-Gerät ausgewählt.&lt;br /&gt;
&lt;br /&gt;
In den Fällen 1 und 2 wird keine Prüfung durchgeführt, ob das gewählte IO-Gerät überhaupt von dem eigenen Modul Daten verarbeiten kann. Im Fehlerfall wird beim Aufruf von [[#IOWrite|IOWrite()]] eine Fehlermeldung im Logfile erzeugt.&lt;br /&gt;
&lt;br /&gt;
Das gefundene IO-Gerät wird mittels Hash-Referenz unter &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; gespeichert. Sollte kein passendes IO-Gerät gefunden werden, wird eine Meldung im Logfile produziert.&lt;br /&gt;
&lt;br /&gt;
Generell sollte bei logischen Modulen die Funktion AssignIoPort() im Rahmen der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion aufgerufen werden, da sonst kein Senden von Daten via [[#IOWrite|IOWrite()]] möglich ist. Für den Empfang ist &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; ohne Bedeutung.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, für welche ein IO-Gerät zugewiesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$proposedName&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
| Der Gerätename, welcher als IO-Gerät verwendet werden soll. Übersteuert die interne Suche nach einem passenden Gerät. Sollte nur verwendet werden, wenn bei mehreren IO-Geräten die Kommunikation nur bspw. über das empfangene IO-Gerät durchgeführt werden kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dispatch ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$found = Dispatch($hash, $message);&lt;br /&gt;
$found = Dispatch($hash, $message, $additional_values, $no_unknown);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() versucht die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;, welche die Definition mit dem Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; erhalten hat, an eine untergeordnete logische Definition weiterzureichen. Über diese Funktion werden Daten von einer physischen Definition an logische Definitionen verteilt. Optional können zur reinen Nachricht auch zusätzliche Daten in &amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt; mitgegeben werden (z.B. Empfangspegel, Signalqualität, ...). Diese Daten werden bei der gefundenen logischen Gerätedefinition als zusätzliche Internals gesetzt. Bei gesetzem Attribut &amp;lt;code&amp;gt;addvaltrigger&amp;lt;/code&amp;gt; in der physischen Definition werden für diese Daten zusätzlich Events erzeugt (keine Readings!). Über das Flag &amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt; kann man verhindern, dass für diese Nachricht im Falle einer nicht gefundenen logischen Gerätedefinition, ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt (und ggf. das zugehörige Modul nachgeladen) wird. &lt;br /&gt;
&lt;br /&gt;
Die Funktion prüft dabei alle Module aus der [[DevelopmentModuleIntro#Die_Client-Liste|Client-Liste]], ob diese mit der Nachricht etwas anfangen können (via Match-Regexp), führt eine optionale Duplikatserkennung via [[DevelopmentModuleIntro#X_Fingerprint|Fingerprint]]-Funktion durch und gibt den Definitionsnamen zurück, welcher die Nachricht erfolgreich via [[DevelopmentModuleIntro#X_Parse|Parse]]-Funktion verarbeiten konnte (z.B. Erzeugen von Readings, Logmeldungen, usw.). &lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche eine Nachricht an andere Module (bzw. deren Definitionen) weiterreichen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Nachricht als Zeichenkette, welche durch ein anderes Modul verarbeitet werden soll. Hier sind nur Zeichenketten erlaubt, da die möglichen Empfängermodule über reguläre Ausdrücke die Nachricht prüfen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$additional_values&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Zusätzliche Daten als Hash-Referenz, welche bei der gefundenen logischen Definition als Internals nach dem Schema &amp;lt;code&amp;gt;&amp;amp;lt;IO-Gerätname&amp;amp;gt;_&amp;amp;lt;Schlüssel&amp;amp;gt;: &amp;amp;lt;Wert&amp;amp;gt;&amp;lt;/code&amp;gt; gesetzt werden. Dies kann bspw. der Empfangspegel (RSSI) oder die Rohnachricht sein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$no_unknown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
| Flag. Wenn gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; zugehöriges Modul basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und &amp;lt;u&amp;gt;kein&amp;lt;/u&amp;gt; entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; nicht von bereits existierenden Definition verarbeitet werden können.  Wenn dieses Flag den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird ggf. das zugehörige Modul für die Nachricht basierend auf der [[DevelopmentModuleIntro#Die_Match-Liste|Match-Liste]] nachgeladen und ein entsprechendes [[DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29|Event]] erzeugt, sollte keine passende Definition für diese Nachricht existieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$found &amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Eine Array-Referenz, welcher die gefundene Definition zu der Nachricht enthält. Wenn keine Definition gefunden wurde, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IOWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = IOWrite($hash, @arguments);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion IOWrite() übergibt die Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; der logischen Definition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; an das ausgewählte IO-Gerät indem es die [[DevelopmentModuleIntro#X_Write|Write]]-Funktion mit den Daten &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; aufruft. In &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; ist üblicherweise eine Nachricht/Frame, sowie evtl. Zusatzdaten enthalten, welche das IO-Gerät nur noch an die verbundene Hardware übermitteln muss. Das kann ein einzelner Skalar mit der entsprechenden Nachricht sein, es können aber auch mehrere Werte übergeben werden. Die Aufrufsyntax muss dabei mit der [[DevelopmentModuleIntro#X_Write|Write]]-Funktion des entsprechenden physikalischen Moduls harmonieren. &lt;br /&gt;
&lt;br /&gt;
Damit IOWrite() funktionieren kann, muss zunächst ein IO-Gerät mittels [[#AssignIoPort|AssignIoPort()]] zugewiesen werden. Dieser Aufruf wird üblicherweise in der [[DevelopmentModuleIntro#X_Define|Define]]-Funktion oder der [[DevelopmentModuleIntro#X_Notify|Notify]]-Funktion (Trigger auf &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt;) durchgeführt. Erst nach dem Aufruf reicht IOWrite() die Daten an das entsprechende IO-Gerät weiter.&lt;br /&gt;
&lt;br /&gt;
Der Inhalt von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; wird nicht an die Write-Funktion übergeben. Sollte man &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; des logischen Gerätes auch im physikalischen Gerät benötigen, so kann man &amp;lt;code&amp;gt;$hash&amp;gt;&amp;lt;/code&amp;gt; mit in &amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt; übergeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die Hash-Referenz der Definition, welche Daten an ihr IO-Gerät übertragen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@arguments&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
| Die zu übertragenden Daten. Das Inhaltsschema muss dabei mit dem entgegennehmenden Modul harmonisieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
| Der Rückgabewert der Write-Funktion des IO-Gerätes, welches die Daten verarbeitet hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
=== InternalTimer===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;InternalTimer($timestamp, $functionName, $arg);&lt;br /&gt;
InternalTimer($timestamp, $functionName, $arg, $waitIfInitNotDone);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion InternalTimer() ermöglicht das verzögerte Ausführen von einer bestimmten Funktion zu einem späteren Zeitpunkt. Die übergebene Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; wird dabei zum Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; mit dem Parameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Angabe eines UNIX-Timestamp, wann der Timer ausgeführt werden soll (bspw: &amp;lt;code&amp;gt;gettimeofday() + 30&amp;lt;/code&amp;gt; um in 30 Sekunden etwas zu starten)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche ausgeführt werden soll zum angegebenen Zeitpunkt (bspw: &amp;quot;MODULNAME_GetStatus&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter welchen die genannte Funktion zum Ausführungszeitpunkt erhalten soll. Typischerweise ist das meistens $hash, kann aber auch eine Zeichenkette oder jeder weitere Datentyp sein, der mit einem Skalar übergeben werden kann (kein direktes Array/Hash).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$waitIfInitNotDone&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| &lt;br /&gt;
&#039;&#039;&#039;ACHTUNG: Dieser Parameter sollte unter keinen Umständen verwendet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieser Parameter verändert das Verhalten von InternalTimer() während der Initialisierung von FHEM. Ist dieser Parameter auf 1 gesetzt und FHEM noch in der Initialisierungsphase (Konfiguration einlesen), so wird ein Sleep des Hauptprozess durchgeführt, bis der gewünschte Zeitpunkt &amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt; erreicht ist. Dadurch wird der gesamte FHEM-Prozess solange blockiert und ist in dieser Zeit nicht ansprechbar. Dieses Verhalten ist besonders relevant bei der Nutzung von InternalTimer() in der [[DevelopmentModuleIntro#X_Define|Define-Funktion]] eines Moduls und sollte daher so keinesfalls benutzt werden. Um Funktionsaufrufe zu verzögern, bis die Initialisierung beendet ist, sollte auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; in der [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] gewartet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RemoveInternalTimer ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;RemoveInternalTimer($arg);&lt;br /&gt;
RemoveInternalTimer($arg, $functionName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion RemoveInternalTimer löscht möglicherweise noch anstehende Timer welche mit dem Übergabeparameter &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gescheduled sind. Optional kann man zusätzlich die Suche auf eine bestimmte Funktion &amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt; weiter einschränken.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Übergabeparameter nach welchem gesucht wird. Alle Timer die mit diesem Übergabeparameter noch anstehen, werden dabei gelöscht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$functionName&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Der Funktionsname der zusätzlich zu &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; gesucht werden soll.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SetExtensionsCancel ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;SetExtensionsCancel($hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion &#039;&#039;SetExtensionsCancel&#039;&#039; löscht möglicherweise noch anstehenden Timer, der durch ein &#039;&#039;on-for-timer&#039;&#039;, &#039;&#039;off-for-timer&#039;&#039;, ... über die &#039;&#039;SetExtensions&#039;&#039; angelegt wurde. Sollte in der [[DevelopmentModuleIntro#X_Set|SetFn]] aufgerufen werden, bevor der Devicezustand durch ein anderes Kommando geändert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Hash-Referenz der Definition, durch die der Timer angelegt wurde.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Definitionen ==&lt;br /&gt;
&lt;br /&gt;
=== devspec2array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
@list = devspec2array($devspec);&lt;br /&gt;
@list = devspec2array($devspec, $client_hash);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion devspec2array() gibt eine Array mit Definitionsnamen zurück die auf die übergebene Device-Specification &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; matchen. &lt;br /&gt;
&lt;br /&gt;
Sollte keine Definition auf die übergebene Spezifikation passen, so wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; als einziges zurückgegeben. Dieser Mechanismus ist aus historischen Gründen so gewählt um die Funktion devspec2array() transparent in Module einzufügen ohne große Änderungen im Code durchführen zu müssen. Daher ist es notwendig im Falle der Rückgabe eines einzelnen Elements dies nochmals auf Existenz in &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; zu prüfen.&lt;br /&gt;
&lt;br /&gt;
Die genaue Syntax einer Device-Specification ist in der {{Link2CmdRef|Anker=devspec}} erläutert. Die Funktion devspec2array() setzt diese Syntax um und gibt die gefundenen Definitions-Namen zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Device-Specification zum Suchen nach Definitions-Namen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039; &lt;br /&gt;
|| Der Definitions-Hash der für den Aufruf verantwortlich ist. Dies dient zur Prüfung, ob diese Definition diesen Vorgang ausführen darf (Vorgangs-Typ: &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@list&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Array mit einer Liste aller Definitions-Namen die zu der übergebenen Device-Specification passen. Sofern keine Definition auf die Spezifikation passt wird &amp;lt;code&amp;gt;$devspec&amp;lt;/code&amp;gt; unverändert zurückgegeben. Wenn &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; gesetzt ist und die Definition diesen Vorgang nicht ausführen darf, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== goodDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$valid = goodDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion goodDeviceName() prüft, ob der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ein gültiger Bezeichner innerhalb von FHEM ist. Ein gültiger Definitionsname besteht aus folgenden Zeichen bzw. Zeichengruppen:&lt;br /&gt;
&lt;br /&gt;
* Normale Buchstaben ohne deutsche Sonderzeichen (A-Z, groß/klein)&lt;br /&gt;
* Zahlen (0-9)&lt;br /&gt;
* Punkt &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;&lt;br /&gt;
* Unterstrich &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der Definitionsname gültig sein, gibt die Funktion als Rückgabewert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Definitionsname aus gültigen Zeichen besteht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$return&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Wahrheitswert, ob der übergebene Definitionsname zulässig ist.&lt;br /&gt;
Folgende Werte sind möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definitionsname enthält unzulässige Zeichen&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definitionsname besteht aus zulässigen Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== makeDeviceName ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$validName = makeDeviceName($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion makeDeviceName() entfernt aus dem übergebenen Definitionsnamen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; alle ungültigen Zeichen und ersetzt diese durch einen Unterstrich &amp;quot;_&amp;quot;. Als Rückgabewert erhält man nun einen konformen Definitionsnamen in dem nur noch erlaubte Zeichen (Buchstaben, Zahlen, Punkt sowie Unterstrich) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$validName&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der modifizierte Name, welcher übergeben wurde, ohne ungültige Zeichen. Alle evtl. ungültigen Zeichen sind durch einen Unterstrich ersetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten abfragen/auslesen ==&lt;br /&gt;
&lt;br /&gt;
=== ReadingsVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = ReadingsVal($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsVal() gibt den inhaltlichen Wert des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings welcher ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = ReadingsTimestamp($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsTimestamp() gibt den Zeitstempel des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Zeitstempel für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches der Zeitstempel ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel des gewünschten Readings in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsAge===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$seconds = ReadingsAge($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsAge() gibt die Dauer in Sekunden seit der letzten Aktualisierung des Readings &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Es handelt sich hierbei um den Zeitpunkt an dem das Reading zuletzt gesetzt/aktualisiert wurde. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem die Dauer der letzten Aktualisierung für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings für welches die Dauer der letzten Aktualisierung ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$seconds&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Sekunden als Ganzzahl, welche seit der letzten Aktualisierung vergangen sind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ReadingsNum ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$number = ReadingsNum($name, $reading, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion ReadingsNum() extrahiert einen numerischen Wert aus dem Reading &amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; und gibt diesen zurück. Dabei werden Zeichenketten wie z.B. Einheiten eliminiert und nur die eigentliche Zahl (Ganzzahl- oder Fließkommazahl) zurückgegeben. Sollte das gewünschte Reading nicht existieren, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben. Sollte das gewünschte Reading existieren, jedoch keinen numerischen Wert enthalten, wird ebenfalls &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem ein numerischer Wert für das gewünschte Reading ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$reading&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Readings aus dem ein numerischer Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Reading nicht existiert, bzw. keinen numerischen Wert enthält.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$number&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Numerischer Wert des gewünschten Readings oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AttrVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = AttrVal($name, $attribute, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion AttrVal() gibt den aktuell konfigurierten Inhalt des Attribut &amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Attribut nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Attribut ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attribute&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Attribut nicht existiert.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Attributs oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== InternalVal ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = InternalVal($name, $internal, $default);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion InternalVal() gibt den aktuellen Inhalt eines Internals &amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte das gewünschte Internal nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem das gewünschte Internal ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$internal&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Internals, dessen Wert ausgelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Standardwert der zurückgegeben werden soll, sofern das Internal nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Inhalt des gewünschten Internal oder &amp;lt;code&amp;gt;$default&amp;lt;/code&amp;gt;, wenn es nicht existiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = Value($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Value() gibt den aktuellen Status von Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldValue===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$value = OldValue($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldValue() gibt den Status der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; zurück BEVOR der aktuelle Status aufgrund eines Events gesetzt wurde. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || vorheriger Status der gewünschten Definition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== OldTimestamp===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$timestamp = OldTimestamp($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion OldTimestamp() gibt den Zeitpunkt der letzten Statusänderung der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; als Zeichenkette zurück. Sollte die gewünschte Definition nicht existieren bzw. nicht gesetzt sein, wird &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name aus dem der Status ausgelesen werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timestamp&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Zeitstempel in lokaler Zeitzone im Format&lt;br /&gt;
&amp;lt;code&amp;gt;2016-02-16 19:34:24&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attribute in anderen Definitionen bereitstellen ==&lt;br /&gt;
&lt;br /&gt;
=== addToAttrList===&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToAttrList($attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in allen systemweiten Definitionen verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für alle Definitionen verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== addToDevAttrList ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
addToDevAttrList($name, $attrib);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion addToDevAttrList() fügt das Attribut mit dem Namen &amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt; zu dem Attribut &amp;lt;code&amp;gt;userattr&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; hinzu. Damit kann dieses Attribut in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verwendet und gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für welche das Attribut verfügbar gemacht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$attrib&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name des Attributs, welches für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; verfügbar gemacht werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Daten dauerhaft schreiben/lesen ==&lt;br /&gt;
&lt;br /&gt;
=== FileRead ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
($error, @content) = FileRead($filename);&lt;br /&gt;
($error, @content) = FileRead($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileRead() liest den Inhalt der Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; ein und gibt diesen als ein zeilenweises Array zurück. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelesen. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die eingelesen werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (Leerstring).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Inhalt der gewünschten Datei als zeilenweises Array. Im Falle eines Fehlers beim Lesen trägt dieses Array den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileDelete ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileDelete($filename);&lt;br /&gt;
$error = FileDelete($param);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileDelete() löscht die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig aus der Datenbank gelöscht. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert das Löschen der Datei im Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei die gelöscht werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad zu der gewünschten Datei.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Löschen der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Löschvorgang erfolgreich, enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FileWrite ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$error = FileWrite($filename, @content);&lt;br /&gt;
$error = FileWrite($param, @content);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion FileWrite() schreibt den übergebenen Inhalt &amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt; in die Datei &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;. In Verwendung mit configDB wird die Datei standardmäßig in die Datenbank geschrieben. Um im Falle von configDB dennoch auf das Dateisystem zugreifen zu können muss als Übergabeparameter ein Hash &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; gesetzt werden in dem ein spezieller Wert den Zugriff auf das Dateisystem forciert.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Dateisystempfad der Datei in welche der Inhalt geschrieben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Um im Falle der Nutzung von configDB den Zugriff auf das lokale Dateisystem zu erzwingen muss ein Parameter-Hash wie folgt übergeben werden:&lt;br /&gt;
&amp;lt;code&amp;gt;{ FileName =&amp;gt; $filename, ForceType =&amp;gt; &amp;quot;file&amp;quot;, NoNL =&amp;gt; 0 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$filename&amp;lt;/code&amp;gt; enthält dabei den lokalen Dateisystempfad der zu schreibenden Datei. Optional kann man den Wert &amp;lt;code&amp;gt;NoNL&amp;lt;/code&amp;gt; auf 1 setzen um kein Newline (&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt;) als Trennzeichen zwischen den einzelnen Zeilen zu erzeugen.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@content&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die zu schreibenden Daten als ein Array von Zeilen (ohne Newline am Ende jeder Zeile).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Datei ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== setKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$error = setKeyValue($key, $value)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion setKeyValue() speichert die Daten &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; unter dem Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; ab. Die Daten werden in einer Datei auf dem Dateisystem (oder configDB) gespeichert und sind somit persistent auch nach einem Neustart von FHEM verfügbar. Die Daten welche in &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; enthalten sind, dürfen dabei keine Zeilenumbrüche enthalten. Sollten Daten mit Zeilenumbrüchen auf diese Weise gespeichert werden, so müssen Zeilenumbrüche durch entsprechende Mechanismen (z.B. Base64 oder das Ersetzen durch alternative Trennzeichen) eliminiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Die Daten werden im Klartext in einer Datei auf dem Dateisystem abgelegt! Sensible Daten die mit setKeyValue gespeichert werden (z.B. Passwörter, Zugangsdaten, etc.) sollten durch entsprechende Mechanismen (z.B. Verschlüsselung) unleserlich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten abgespeichert werden soll (bspw. Definitions-Namen). Der Schlüssel darf dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Die zu speichernden Daten als Zeichenkette ohne Zeilenumbruch. Die Daten dürfen dabei keine Zeilenumbrüche enthalten.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, werden zuvor gespeicherte Daten gelöscht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Schreiben der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Schreibvorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getKeyValue ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;($error, $value) = getKeyValue($key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getKeyValue() gibt Daten, welche zuvor per &amp;lt;code&amp;gt;setKeyValue()&amp;lt;/code&amp;gt; gespeichert wurden, zurück.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der eindeutige Schlüssel als Zeichenkette unter dem die Daten gespeichert wurden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewert:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabe!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Im Falle eines Fehlers beim Lesen der Daten ist dieser Wert mit einer Fehlermeldung als Zeichenkette gefüllt. Ist der Lesevorgang erfolgreich enthält &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Daten, welche unter dem gegebenen Schlüssel &amp;lt;code&amp;gt;$key&amp;lt;/code&amp;gt; hinterlegt sind. Wenn keine Daten zu dem Schlüssel existieren, besitzt &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
=== Log ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log($verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem globalen Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; ist. Wenn &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; größer ist als das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;, wird die Meldung nicht geloggt.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Log3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3($name, $verbose, $message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Log3() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; in das FHEM-Logfile, sofern &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; kleiner gleich dem Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; ist. Wenn das Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; in der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht gesetzt ist, wird gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist primär für die Log-Ausgabe in Modulen gedacht um so dem User die Möglichkeit zu geben nur für bestimmte Definitionen den Verbose-Level zu erhöhen ohne den globalen Verbose-Level zu erhöhen.&lt;br /&gt;
 &lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Der Name der Definition wogegen geprüft werden soll. Wenn &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in FHEM nicht existiert, oder den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; besitzt, wird der Parameter &amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt; gegen das globale Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt; geprüft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$verbose&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Verbose-Level unter dem die Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; geloggt werden soll. &lt;br /&gt;
&lt;br /&gt;
Ganzzahl zwischen 0 und 5&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Log-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Debug($message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion Debug() schreibt die Meldung &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; mit dem Präfix &amp;lt;code&amp;gt;DEBUG&amp;gt;&amp;lt;/code&amp;gt; in das FHEM-Logfile. Diese Funktion ist zum temporären Debuggen gedacht und sollte nicht fest in einem Modul verwendet werden. Sie entspricht dem Aufruf:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 Log(1, &amp;quot;DEBUG&amp;gt;&amp;quot;.$message);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Debug-Meldung als Zeichenkette, welche in das FHEM-Logfile geloggt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Status-Abfragen ==&lt;br /&gt;
=== IsDevice ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDevice($name);&lt;br /&gt;
$status = IsDevice($name, $type);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDevice() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existiert. Optional kann man prüfen, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; dem Modultyp &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entspricht. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition existiert, bzw. einem bestimmten Modultyp entspricht.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher auf Vorhandensein geprüft werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Ein regulärer Ausdruck der gegen den Modulnamen (&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;) der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; geprüft werden soll. Dieser Ausdruck muss auf den gesamten Modulnamen passen, da der Ausdruck mit &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; umschlossen wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Das Ergebnis, ob eine solche Definition existiert:&lt;br /&gt;
&lt;br /&gt;
0 - Definition existiert nicht&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition existiert&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn nur &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; übergeben ist, wird nur geprüft ob eine Definition mit diesem Namen existiert. Wenn zusätzlich &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; parametrisiert wurde, muss eine Definition mit dem Namen &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; existieren &#039;&#039;&#039;UND&#039;&#039;&#039; dem Modultypen &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt; entsprechen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDisabled ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDisabled($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDisabled() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; aktuell deaktiviert  (Attribute: disabled/disabledForIntervals) oder durch den Nutzer inaktiv geschaltet wurde (STATE: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;). Je nachdem ob die Definition deaktiviert/inaktiv ist, gibt sie einen entsprechenden Wert größer &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück. Wenn die Definition aktiv ist, gibt die Funktion den Wert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition aktiv/inaktiv ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
2 - Definition ist durch das Attribut &amp;lt;code&amp;gt;disabledForIntervals&amp;lt;/code&amp;gt; deaktiviert&amp;lt;br&amp;gt;&lt;br /&gt;
3 - Definition ist durch den User inaktiv geschaltet. Dies bedeutet &amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt; oder das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; der Definition besitzt den Wert &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsDummy() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn die Definition in den Dummy-Modus gesetzt ist, gibt IsDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIgnored ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIgnored($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIgnored() prüft, ob die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; durch den User ignoriert wird (Attribut: &amp;lt;code&amp;gt;ignore&amp;lt;/code&amp;gt;). Wenn die Definition durch den User ignoriert wird, gibt IsIgnored() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob eine Definition ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name welcher geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - Definition wird ignoriert&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IsIoDummy ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = IsIoDummy($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion IsIoDummy() prüft, ob das zugeordnete IO-Device der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; in den Dummy-Modus versetzt wurde (Attribut: &amp;lt;code&amp;gt;dummy&amp;lt;/code&amp;gt;). Wenn das IO-Device in den Dummy-Modus gesetzt ist, gibt IsIoDummy() den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück, andernfalls &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein IO-Device einer Definition im Dummy-Modus ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitions-Name, dessen IO-Device geprüft werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Status des IO-Devices der Definition. Je nach Status sind folgende Werte möglich:&lt;br /&gt;
&lt;br /&gt;
0 - IO-Device der Definition ist aktiv&amp;lt;br&amp;gt;&lt;br /&gt;
1 - IO-Device der Definition ist im Dummy-Modus&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
&lt;br /&gt;
=== Authenticate ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authenticate($client, $argument);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Authorized ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$result = Authorized($client_hash, $type, $arg);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() prüft, ob ein Client mit dem Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf bzw. dazu berechtigt ist. Dazu werden sämtliche Definitionen in FHEM befragt, deren Module die Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereitstellen. Die beiden Argumente &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; werden dabei 1:1 an die [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion der jeweiligen Module übergeben. &lt;br /&gt;
&lt;br /&gt;
Nachdem alle Definitionen zu dem jeweiligen Vorgang befragt wurden, gibt die Funktion zurück, ob der Client dazu authorisiert ist. Sobald eine Definition den Vorgang explizit verbietet, wird sofort der Rückgabewert &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; zurückgegeben. Wenn eine Definition den Vorgang explizit erlaubt, wird sofort der Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurückgegeben. In beiden Fällen werden weitere Definitionen nicht mehr befragt. Sollte keine Definition den Vorgang explizit erlauben/verbieten oder keine Definition zum Prüfen vorhanden sein, wird die Aktion generell erlaubt durch die Rückgabe von &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. Sollte ebenfalls keine Bewertung möglich sein aufgrund eines fehlenden oder unvollständigen Client-Hash, wird der Vorgang generell erlaubt.&lt;br /&gt;
&lt;br /&gt;
Innerhalb von FHEM werden zwei Vorgangstypen bereits verwendet um die Befehlsausführung und Sichtbarkeit von Definitionen in FHEM einzuschränken. Das Modul [[allowed]] stellt dabei die entsprechende Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]] bereit.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Authorized() ist daher nur notwendig, wenn man weiterführende Beschränkungen für einzelne Clients in Modulen/Definitionen realisieren möchte, die über die bestehenden Möglichkeiten hinausgehen. Dazu muss natürlich ein entsprechendes Gegenstück in Form eines weiteren Moduls zur Verfügung stehen, welche diese neuen Vorgangstypen entsprechend bewerten kann. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob ein Client zu einem bestimmten Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Client-Hash, welcher einen Vorgang durchführen möchte.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Vorgangstyp als Zeichenkette, um welchen es geht. Innerhalb von fhem.pl werden aktuell zwei Typen unterschieden:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; - Befehlsausführung (sowohl FHEM-Befehle als auch Shell-/Perl-Aufrufe)&lt;br /&gt;
* &amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt; - Sichtbarkeit von Definitionen innerhalb von FHEM&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Ein zusätzliches Argument um den jeweiligen Vorgangstyp genauer zu beschreiben. Eine Beschreibung der Bedeutung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; in Verbindung mit den bereits vorhandenen Vorgangstypen (&amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;devicename&amp;lt;/code&amp;gt;) gibt es in der Beschreibung von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; zur Modulfunktion [[DevelopmentModuleIntro#X_Authorize|X_Authorize()]]&lt;br /&gt;
&lt;br /&gt;
Generell können hier weitere Typ/Argument-Kombinationen verwendet werden, solange es ein korrespondierendes Modul mit [[DevelopmentModuleIntro#X_Authorize|Authorize]]-Funktion gibt, welches diese Vorgänge verarbeiten kann.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|| Ergebnis, ob der zu prüfende Vorgang authorisiert ist.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - Vorgang ist NICHT authorisiert und darf nicht ausgeführt werden.&lt;br /&gt;
* &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Vorgang ist authorisiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ausführen == &lt;br /&gt;
&lt;br /&gt;
=== CallFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallFn() ruft von der Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; die im Modul registrierte Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; mit den Argumenten &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; auf und gibt das Ergebnis dieses Funktionsaufrufs zurück. Dazu wird die Funktion im entsprechenden Modul-Hash des zugrunde liegenden Moduls von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Entsprechende Funktionen werden im Rahmen der [[DevelopmentModuleIntro#X_Initialize|Initialize]]-Funktion beim Laden eines Moduls registriert. &lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte das zugrunde liegende Modul die entsprechende Funktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modulfunktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]] im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;SetFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;CopyFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CallInstanceFn ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
@ret = CallInstanceFn($name, $function_name, @args);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Die Funktion CallInstanceFn() ist eine Erweiterung zu [[#CallFn|CallFn()]]. Die auszuführende Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; wird dabei zuerst in dem Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; gesucht. Der Funktionsname muss dabei direkt in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; definiert sein (ähnlich wie beim Modul-Hash im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]]). Der Funktionsname kann in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; dabei optional mit einem Punkt als Präfix vorangestellt sein um eine Anzeige in FHEMWEB zu unterbinden. Sollte die Funktion &amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt; innerhalb des Definitions-Hash von &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; nicht existieren, wird [[#CallFn|CallFn()]] mit den gleichen Parametern aufgerufen um die Funktion im zugrunde liegenden Modul aufzurufen, sofern diese ebenfalls existiert.&lt;br /&gt;
&lt;br /&gt;
Dadurch kann man eine registrierte Modulfunktion definitionsbezogen in Einzelfällen übersteuern durch bspw. äquivalente Modulfunktionen aus Hilfsmodulen.&lt;br /&gt;
&lt;br /&gt;
Bei einem erfolgreichen Aufruf gibt CallInstanceFn() den/die Rückgabewert/-e der Modulfunktion zurück. Sollte sowohl die Definition, als auch das zugrunde liegende Modul die entsprechende Modulfunktion nicht bereitstellen, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Definition, für den ein Aufruf einer Modul-Funktion durchgeführt werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$function_name&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Name der Funktion als Zeichenkette, welche aufgerufen werden soll. Dieser Wert entspricht dem Schlüsselwort mit dem die entsprechende Funktion in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; und, im Rahmen von [[DevelopmentModuleIntro#X_Initialize|X_Initialize()]], im Modul-Hash registriert wurde.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;DbLog_splitFn&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eines oder mehrere Argumente, welche beim Aufruf der Modulfunktion entsprechend mitgegeben werden sollen. Die Argumente sind hier je nach Modulfunktion unterschiedlich. Die Aufrufsyntax und deren Reihenfolge muss in Modulen, welche die entsprechende Modulfunktion unterstützen in gleicher Art und Weise implementiert werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$ret&amp;lt;/code&amp;gt;&#039;&#039;&#039; / &#039;&#039;&#039;&amp;lt;code&amp;gt;@ret&amp;lt;/code&amp;gt;&#039;&#039;&#039;  || Der Rückgabewert der Modulfunktion als Skalar oder Array (je nach Kontext).&lt;br /&gt;
&lt;br /&gt;
Sollte die gewünschte Funktion in der Definition, als auch im zugrunde liegenden Modul nicht existieren, wird nur &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
=== configDBUsed ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$status = configDBUsed();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion configDBUsed() prüft, ob in der aktuellen FHEM-Umgebung configDB verwendet wird und gibt in diesem Fall den Wert &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; zurück. Die Funktion besitzt keinerlei Übergabeparameter.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion kann dabei in typischen if-Konstrukten direkt verwendet werden um zu prüfen, ob configDB verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$status&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Folgende Werte sind möglich:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0 - configDB wird nicht verwendet&amp;lt;br&amp;gt;&lt;br /&gt;
1 - configDB wird  verwendet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== getUniqueId ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$uniqueID = getUniqueId();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion getUniqueId() gibt einen eindeutige Identifikations-String der lokalen FHEM-Installation zurück. Dieser String wird einmalig per Zufallsalgorithmus erzeugt und anschließend lokal abgespeichert. Jede FHEM-Installation besitzt einen anderen Identifikations-String. Dieser Wert wird bspw. für die Online-Statistik verwendet um die einzelnen Installation zu anonymisieren.&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$uniqueID&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Eine Zeichenkette in Hexadezimaldarstellung welche pro Installation eindeutig ist.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== toJSON ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$jsonString = toJSON($value);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion toJSON() konvertiert eine komplexe Datenstruktur, welche aus Array, Hashes oder Skalaren bestehen kann, in einen JSON-konformen String. Als Argument &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; kann man daher eine Array-Referenz, eine Hash-Referenz oder einen einfachen, skalaren Wert übergeben. Als Rückgabewert wird ein JSON-konformer String zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&amp;lt;br&amp;gt;can be &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;&#039;&#039;&lt;br /&gt;
|| Eine Array-Referenz, eine Hash-Referenz oder ein einfacher, skalarer Wert, welcher in JSON zurückgeben werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$jsonString &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der JSON-String, welcher das Objekt samt Inhalt darstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CancelDelayedShutdown ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
CancelDelayedShutdown($name);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion CancelDelayedShutdown() ist nur im Zusammenhang mit einer im Modul implementierten [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdown]]-Funktion notwendig. Sofern über die DelayedShutdown-Funktion ein verzögertes Herunterfahren von FHEM signalisiert wird, dient CancelDelayedShutdown() dazu FHEM zu signalisieren, dass alle notwendigen Schritte vor dem Herunterfahren für die Definition &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt; abgeschlossen sind und FHEM sich nun beenden kann.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Definitionsname, für den die Shutdown-Verzögerung abgebrochen werden soll&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Event-on-update-reading&amp;diff=34706</id>
		<title>Event-on-update-reading</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Event-on-update-reading&amp;diff=34706"/>
		<updated>2021-02-03T20:13:58Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Typos, Klarstellung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SEITENTITEL:event-on-update-reading}}  &amp;lt;!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dem Attribut [[event-on-update-reading]] kann für Readings eines Gerätes festgelegt werden, dass bei jeder Aktualisierung ein Event (und damit in der Regel auch ein Log-Eintrag) erzeugt werden soll. Da dies das Defaultverhalten von FHEM ist, ist event-on-update-reading nur dann sinnvoll einsetzbar, wenn das Defaultverhalten vorher mit dem Attribut [[event-on-change-reading]] eingeschränkt wurde.&lt;br /&gt;
&lt;br /&gt;
Wird &#039;&#039;event-on-update-reading&#039;&#039; für ein einzelnes Reading gesetzt, werden zunächst alle übrigen Readings nicht mehr protokolliert, erzeugen also keine Events mehr.&lt;br /&gt;
== Einführung ==&lt;br /&gt;
FHEM erzeugt für jedes gemeldete Reading ein Event, egal, ob das Reading sich geändert hat, oder nur Intervallweise per Update aktualisiert wurde. Dieses Verhalten kann Nachteile haben und daher mit [[event-on-change-reading]] für ein Gerät abgestellt werden.&lt;br /&gt;
&lt;br /&gt;
[[event-on-update-reading]] dient dazu, für &#039;&#039;&#039;einzelne&#039;&#039;&#039; Readings des Gerätes das Standardverhalten wieder herzustellen, sollte es für bestimmte Readings in einer gegeben FHEM Installation sinnvoll sein, doch bei jedem Update auch ohne Werteänderung ein Event zu erhalten. Dies kann z.b. bei der Erzeugung von Graphen notwendig sein.&lt;br /&gt;
== Syntax ==&lt;br /&gt;
Das &#039;&#039;event-on-update-reading&#039;&#039; Attribut wird in der folgenden Weise spezifiziert:&lt;br /&gt;
:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;attr &amp;lt;device&amp;gt; event-on-update-reading reading1[,reading2...n]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Die zu berücksichtigenden Readings sind als durch Kommata getrennte Werte anzugeben, können aber auch über reguläre Ausdrücke zusammengefasst werden.&lt;br /&gt;
&lt;br /&gt;
== Wechselwirkungen == &lt;br /&gt;
Dieses Attribut steht in Wechselwirkung mit den Attributen [[event-on-change-reading]] und [[event-min-interval]], bitte beim Einsatz berücksichtigen. Ein Einsatz ohne gleichzeitige event-on-change-reading ist idR. nicht sinvoll.&lt;br /&gt;
&lt;br /&gt;
Sind bei einem Device weder &#039;&#039;event-on-update-reading&#039;&#039; noch  &#039;&#039;event-on-change-reading&#039;&#039; spezifiziert, werden für alle Readings sowohl bei Aktualisierung (mit dem gleichen Wert) als auch bei der Änderung Events erzeugt, dies ist das Standardverhalten. Sobald jedoch eines der beiden Attribute gesetzt ist, müssen alle Readings, die protokolliert werden sollen bei (mindestens) einem der Attribute berücksichtigt sein.&lt;br /&gt;
&lt;br /&gt;
Ist für ein Reading sowohl &#039;&#039;event-on-change-reading&#039;&#039; als auch &#039;&#039;event-on-update-reading&#039;&#039; spezifiziert, wird bei jeder Aktualisierung des Readings ein Event erzeugt, das &#039;&#039;event-on-change&#039;&#039; wird für dieses Reading also außer Kraft gesetzt bzw. &amp;quot;überschrieben&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Beispiele ==&lt;br /&gt;
Hat man durch&lt;br /&gt;
:&amp;lt;code&amp;gt;attr &amp;lt;device&amp;gt; event-on-change-reading .*&amp;lt;/code&amp;gt; &lt;br /&gt;
erreicht, dass alle Readings des Gerätes nur noch bei Werteänderung eine Event erzeugen (und somit auch nur dann geloggt werden), kann mit&lt;br /&gt;
:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;attr &amp;lt;device&amp;gt; event-on-update-reading temperature, humidity&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
dafür gesorgt werden, das für Temperatur und Luftfeuchte dennoch mit jedem Update (intervallweise Aktualisierung auch ohne Werteänderung) ein Event erzeugt und geloggt wird.&lt;br /&gt;
&lt;br /&gt;
== Praktische Anwendung ==&lt;br /&gt;
Da mit [[event-min-interval]] ebenfalls dafür gesorgt werden kann, dass Readings auch ohne Werteänderungen ein Event erzeugen, muss beim Einsatz geprüft werden, ob event-min-interval nicht sinnvoller als event-on-update-reading ist. Da die Updateintervalle einiger Geräte recht kurz sind, kann der Einsatz event-on-update-reading immer noch sehr viele (ggf. nutzlose) Events für das gegebene Reading erzeugen.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
*[[event-on-change-reading]]&lt;br /&gt;
*[[event-min-interval]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* Benutzungstipps (&#039;&#039;Best Practice&#039;&#039;) für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Attribut (allgemeingültig)]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=34239</id>
		<title>CPAN</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=34239"/>
		<updated>2020-11-16T09:19:29Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: RPM-Sektion eingefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= CPAN =&lt;br /&gt;
&lt;br /&gt;
Das CPAN, Comprehensive Perl Archive Network, ist ein weltweit verteiltes Netzwerk für Perl-Module, das seit 1995 besteht und aktuell etwa 200 000 Module umfasst.&lt;br /&gt;
&lt;br /&gt;
Siehe auch hier eine [https://www.cpan.org/modules/INSTALL.html Zusammenfassung des CPAN-Projektes].&lt;br /&gt;
&lt;br /&gt;
== Clients ==&lt;br /&gt;
&lt;br /&gt;
=== Plattformunabhängig ===&lt;br /&gt;
&lt;br /&gt;
Das CPAN bietet drei plattformunabhängige Clients an, von denen zwei hier beschrieben werden. Die &#039;&#039;Empfehlung&#039;&#039; ist, &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; zu nutzen.&lt;br /&gt;
&lt;br /&gt;
==== cpanminus ====&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/distribution/App-cpanminus/bin/cpanm cpanminus] (&amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt;) ist der bevorzugte Weg, wie CPAN-Pakete installiert werden sollten. cpan-minus ist, wie &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; ein CPAN-Paket, das aber auch für viele Betriebssystem als fertiges Paket portiert wurde.&lt;br /&gt;
&lt;br /&gt;
cpan-minus bietet einen [http://cpanmin.us/ Quickstart] an, der auf jedem System läuft, auf dem Perl installiert ist. Dazu muss folgender Befehl auf der Kommandozeile ausgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;curl -L https://cpanmin.us | perl - App::cpanminus&amp;lt;/pre&amp;gt;&lt;br /&gt;
Aus Sicherheitsgründen sollte vor Ausführung des Befehls überprüft werden, was unter [http://cpanmin.us/ cpanmin.us] zu finden ist, da ggf. Schadcode unbemerkt eingeschmuggelt werden könnte.&lt;br /&gt;
&lt;br /&gt;
Ist der Client &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; installiert, kann mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpanm Paket::Name&amp;lt;/pre&amp;gt;&lt;br /&gt;
ein Paket (in diesem Falle das nicht-existende Paket &amp;lt;code&amp;gt;Paket::Name&amp;lt;/code&amp;gt;) installiert werden. Die Option &amp;lt;code&amp;gt;--sudo&amp;lt;/code&amp;gt; sorgt dafür, dass cpanminus die Installation als Superuser versucht (ggf. muss ein Passwort eingegeben werden).&lt;br /&gt;
&lt;br /&gt;
==== Exkurs: cpan-outdated ====&lt;br /&gt;
&lt;br /&gt;
Das Paket [https://metacpan.org/pod/distribution/cpan-outdated/script/cpan-outdated &amp;lt;code&amp;gt;cpan-outdated&amp;lt;/code&amp;gt;] erzeugt eine cpanminus-kompatible Liste an CPAN-Paketen, die aktualisiert werden können, z.B.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ cpan-outdated &lt;br /&gt;
A/AN/ANDK/CPAN-2.27.tar.gz&lt;br /&gt;
L/LE/LEONT/Test-Harness-3.42.tar.gz&lt;br /&gt;
B/BI/BINGOS/Archive-Tar-2.36.tar.gz&lt;br /&gt;
T/TO/TODDR/autodie-2.32.tar.gz&lt;br /&gt;
R/RU/RURBAN/B-Debug-1.26.tar.gz&lt;br /&gt;
I/IL/ILMARI/bareword-filehandles-0.007.tar.gz&lt;br /&gt;
P/PJ/PJACKLAM/bignum-0.51.tar.gz&lt;br /&gt;
X/XS/XSAWYERX/Carp-1.50.tar.gz&lt;br /&gt;
L/LE/LEEJO/CGI-4.47.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Clone-0.45.tar.gz&lt;br /&gt;
M/ML/MLEHMANN/common-sense-3.75.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Bzip2-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Zlib-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/IO-Compress-2.093.tar.gz&lt;br /&gt;
H/HM/HMBRAND/Config-Perl-V-0.31.tgz&lt;br /&gt;
A/AT/ATOOMIC/TimeDate-2.33.tar.gz&lt;br /&gt;
P/PM/PMQS/DB_File-1.853.tar.gz&lt;br /&gt;
H/HU/HURRICUP/Devel-Camelcadedb-v2019.1.tar.gz&lt;br /&gt;
P/PJ/PJCJ/Devel-Cover-1.36.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Devel-PPPort-3.58.tar.gz&lt;br /&gt;
M/MS/MSHELOR/Digest-SHA-6.02.tar.gz&lt;br /&gt;
R/RJ/RJBS/Email-Sender-1.300034.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Sehr nützlich ist die Kombination aus cpanminus und cpan-outdated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan-outdated | cpanm --sudo&amp;lt;/pre&amp;gt;&lt;br /&gt;
Diese Befehlssequenz aktualisiert alle aktualisierbaren CPAN-Pakete mit Hilfe von cpanminus (als Superuser).&lt;br /&gt;
&lt;br /&gt;
==== cpan ====&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/CPAN &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;] ist der mit jeder Perl-Installation mitgelieferte Client für das CPAN und lässt sich entweder mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;perl -MCPAN -e shell&amp;lt;/pre&amp;gt;&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan&amp;lt;/pre&amp;gt;&lt;br /&gt;
starten. Es wird ein interaktiver Client gestartet; mit &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; kann eine sehr umfangreiche Hilfe aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Ein Modul lässt sich am einfachsten mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan install PAKET::NAME&amp;lt;/pre&amp;gt;&lt;br /&gt;
installieren (hier das nicht-existente Paket &amp;lt;code&amp;gt;PAKET::NAME&amp;lt;/code&amp;gt;). &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; eignet sich weniger gut um Module zu installieren oder zu aktualisieren, aber sehr gut um nach Paketen zu suchen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;i /JSON/&amp;lt;/pre&amp;gt;&lt;br /&gt;
findet jedes Paket, das die Zeichenkette &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; im Bereich Autor, Bundle, Distribution oder Modul enthält. Das sind meist viele Ergebnisse, aber liefert einen Überblick &amp;amp;quot;was geht&amp;amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß ist &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; recht störrisch in der Handhabung. Deshalb empfehle ich die Nutzung von cpanminus.&lt;br /&gt;
&lt;br /&gt;
=== OS-Paketmanager ===&lt;br /&gt;
&lt;br /&gt;
==== Debian und Derivate (Ubuntu, Raspbian, etc.) ====&lt;br /&gt;
&lt;br /&gt;
Vom Debian-Projekt werden viele, aber lange nicht alle, Pakete des CPAN auch als Pakete für den eingebauten Paketmanager &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt; [https://packages.debian.org/stable/perl/ bereitsgestellt]. Dort sind momentan etwa 4 000 Pakete verfügbar, d.h. rund 2% der im CPAN verfügbaren Pakete. Es ist nicht immer trivial, ein Paket zu finden. Ein einfacher Fall ist z.B. das Paket &amp;lt;code&amp;gt;Readonly&amp;lt;/code&amp;gt;, das über &amp;lt;code&amp;gt;cpanm Readonly&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;apt-get install libreadonly-perl&amp;lt;/code&amp;gt; installiert werden könnte. Im Allgemeinen kann man sagen, dass sich der Name des &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;-Paketes aus dem Prefix &amp;lt;code&amp;gt;lib&amp;lt;/code&amp;gt;, gefolgt vom Paketnamen in Kleinbuchstaben, bei dem die &amp;lt;code&amp;gt;::&amp;lt;/code&amp;gt; durch &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt; ersetzt wurden, und dem Suffix &amp;lt;code&amp;gt;-perl&amp;lt;/code&amp;gt; zusammensetzt:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! CPAN&lt;br /&gt;
! Debian-Paket&lt;br /&gt;
|-&lt;br /&gt;
| Rose::URI&lt;br /&gt;
| librose-uri-perl&lt;br /&gt;
|-&lt;br /&gt;
| Sah::Schemas::Rinci&lt;br /&gt;
| libsah-schemas-rinci-perl&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Kein Beispiel wäre vollständig ohne Ausnahme, z.B.:&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;libromana-perligata-perl&amp;lt;/code&amp;gt;] installiert das Perl-Paket [https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;Lingua::Romana::Perligata&amp;lt;/code&amp;gt;], müsste nach der selbstgewählten Konvention aber &amp;lt;code&amp;gt;liblingua-romana-perligata-perl&amp;lt;/code&amp;gt; heißen.&lt;br /&gt;
&lt;br /&gt;
Vorteilhaft ist, dass man die Pakete zusammen mit anderen Debian-Paketen automatisch auf dem aktuellen Stand halten kann, z.B. [https://wiki.debian.org/UnattendedUpgrades &amp;lt;code&amp;gt;unattended-upgrades&amp;lt;/code&amp;gt;] - man spart so eine doppelte Implementierung der Updates.&lt;br /&gt;
&lt;br /&gt;
Wiederum von Nachteil ist, dass man mit einer auf ein Release festgelegten Quelle irgendwann auch keine Updates der Perl-Pakete mehr erhält.&lt;br /&gt;
&lt;br /&gt;
==== SuSE Linux ====&lt;br /&gt;
&lt;br /&gt;
YaST bietet aktuell etwa 3 121 der rund 200 000 Pakete in [https://build.opensuse.org/project/show/devel:languages:perl &amp;lt;code&amp;gt;devel:languages:perl&amp;lt;/code&amp;gt;] an, dazu kommen noch einige Community-Pakete mit einer trivial nicht feststellbaren Anzahl an Paketen. Im Paket [https://build.opensuse.org/package/show/devel:languages:perl:CPAN-A/perl-App-cpanminus &amp;lt;code&amp;gt;perl-App-cpanminus&amp;lt;/code&amp;gt;] ist &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; enthalten.&lt;br /&gt;
&lt;br /&gt;
==== RedHat Linux ====&lt;br /&gt;
Der RPM bietet eine nicht trivial feststellbare Anzahl an Perl-Paketen an, die Gesamtsumme beträgt um die 8000 - inkl. verschiedener Plattformen (i386, etc.). Auch hier lässt sich festhalten, dass die out of the shelf installierbaren Pakete auf einen Bruchteil der im CPAN verfügbaren reduziert.&lt;br /&gt;
&lt;br /&gt;
==== MacOS ====&lt;br /&gt;
&lt;br /&gt;
Für MacOS gilt, dass das installierte Perl den &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;-Client und eine Auswahl an Module mitbringt. &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; lässt sich installieren und sollte auch der Weg der Wahl sein. Es ist außerdem möglich, Pakete über [https://www.macports.org/ MacPorts] zu installieren. MacPorts bietet noch weniger Pakete (aktuell 1 797 für Perl 5.26, 1 799 für Perl 5.28) als Debian.&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
&lt;br /&gt;
[https://www.activestate.com/products/perl/downloads/ ActiveState] bietet eine Perl-Distribution an, die bereits mit einigen Module, 214 bei [https://platform.activestate.com/ActiveState/ActivePerl-5.28 Perl 5.28], ausgeliefert wird.&lt;br /&gt;
&lt;br /&gt;
== Empfohlene Pakete ==&lt;br /&gt;
&lt;br /&gt;
Im FHEM-Umfeld werden aktuell rund 120 CPAN-Pakete (mit Sub-Paketen) eingesetzt die keine [https://www.perl.com/article/what-is-the-perl-core-/ Core-Module] sind und ggf. für ein FHEM-Modul [[Meta|nachinstalliert]] werden müssen:&lt;br /&gt;
&lt;br /&gt;
* Authen::OATH&lt;br /&gt;
* AutoLoader&lt;br /&gt;
* B&lt;br /&gt;
* Carp&lt;br /&gt;
* Color&lt;br /&gt;
* Compress::Zlib&lt;br /&gt;
* Convert::Base32&lt;br /&gt;
* Cpanel::JSON::XS&lt;br /&gt;
* Crypt::Argon2&lt;br /&gt;
* Crypt::CBC&lt;br /&gt;
* Crypt::Cipher::AES&lt;br /&gt;
* Crypt::ECB&lt;br /&gt;
* Crypt::Mode::CBC&lt;br /&gt;
* Crypt::MySQL&lt;br /&gt;
* Crypt::NaCl::Sodium&lt;br /&gt;
* Crypt::Rijndael&lt;br /&gt;
* Crypt::Rijndael_PP&lt;br /&gt;
* Crypt::URandom&lt;br /&gt;
* DBI&lt;br /&gt;
* DBI::Const::GetInfoType&lt;br /&gt;
* Data::Dumper&lt;br /&gt;
* Data::UUID&lt;br /&gt;
* Date::Parse&lt;br /&gt;
* DateTime&lt;br /&gt;
* Device::Firmata&lt;br /&gt;
* Device::Firmata::Base&lt;br /&gt;
* Device::Firmata::Constants&lt;br /&gt;
* Device::Firmata::Error&lt;br /&gt;
* Device::Firmata::Language&lt;br /&gt;
* Device::Firmata::Platform&lt;br /&gt;
* Device::Firmata::Protocol&lt;br /&gt;
* Device::SerialPort&lt;br /&gt;
* Device::USB&lt;br /&gt;
* Digest::CRC&lt;br /&gt;
* Digest::SHA1&lt;br /&gt;
* Encode::Detect::Detector&lt;br /&gt;
* Expect&lt;br /&gt;
* File::HomeDir&lt;br /&gt;
* HTML::Entities&lt;br /&gt;
* HTML::Parser&lt;br /&gt;
* HTTP::Cookies&lt;br /&gt;
* HTTP::Daemon&lt;br /&gt;
* HTTP::Headers&lt;br /&gt;
* HTTP::Request&lt;br /&gt;
* HTTP::Request::Common&lt;br /&gt;
* IO::Interface::Simple&lt;br /&gt;
* IO::Socket::Multicast&lt;br /&gt;
* IO::Socket::Multicast6&lt;br /&gt;
* IO::Socket::SSL&lt;br /&gt;
* IO::Socket::Timeout&lt;br /&gt;
* IO::String&lt;br /&gt;
* Image::ExifTool&lt;br /&gt;
* Image::LibRSVG&lt;br /&gt;
* Image::Size&lt;br /&gt;
* Inline&lt;br /&gt;
* JSON&lt;br /&gt;
* JSON::MaybeXS&lt;br /&gt;
* JSON::XS&lt;br /&gt;
* JSON::backportPP&lt;br /&gt;
* JsonMod::JSON::Path::Node&lt;br /&gt;
* LWP&lt;br /&gt;
* LWP::Simple&lt;br /&gt;
* LWP::UserAgent~6&lt;br /&gt;
* Linux::Inotify2&lt;br /&gt;
* LiquidCrystal&lt;br /&gt;
* Lirc::Client&lt;br /&gt;
* List::MoreUtils&lt;br /&gt;
* MIME::Lite&lt;br /&gt;
* MP3::Info&lt;br /&gt;
* MP3::Tag&lt;br /&gt;
* MP3::Tag::CDDB_File&lt;br /&gt;
* MP3::Tag::Cue&lt;br /&gt;
* MP3::Tag::File&lt;br /&gt;
* MP3::Tag::ID3v1&lt;br /&gt;
* MP3::Tag::ID3v2&lt;br /&gt;
* MP3::Tag::ImageExifTool&lt;br /&gt;
* MP3::Tag::ImageSize&lt;br /&gt;
* MP3::Tag::Inf&lt;br /&gt;
* MP3::Tag::LastResort&lt;br /&gt;
* MP3::Tag::ParseData&lt;br /&gt;
* Mail::IMAPClient&lt;br /&gt;
* Mojolicious~5.54&lt;br /&gt;
* Net::Address::IP::Local&lt;br /&gt;
* Net::Bonjour&lt;br /&gt;
* Net::FTPSSL&lt;br /&gt;
* Net::Jabber&lt;br /&gt;
* Net::MQTT::Constants&lt;br /&gt;
* Net::MQTT::Message&lt;br /&gt;
* Net::MQTT::Message::JustMessageId&lt;br /&gt;
* Net::Rendezvous&lt;br /&gt;
* Net::SIP&lt;br /&gt;
* Net::SIP::Packet&lt;br /&gt;
* Net::SMTP::SSL&lt;br /&gt;
* Net::Telnet&lt;br /&gt;
* Net::UPnP::AV::MediaRenderer&lt;br /&gt;
* Net::UPnP::AV::MediaServer&lt;br /&gt;
* Net::UPnP::ControlPoint&lt;br /&gt;
* Net::UPnP::Device&lt;br /&gt;
* Net::UPnP::Service&lt;br /&gt;
* Net::XMPP::Namespaces&lt;br /&gt;
* Nmap::Parser&lt;br /&gt;
* Path::Tiny&lt;br /&gt;
* Paws::Polly&lt;br /&gt;
* Perl::PrereqScanner::NotQuiteLite&lt;br /&gt;
* RPC::XML::Client&lt;br /&gt;
* RPC::XML::Server&lt;br /&gt;
* RiveScript&lt;br /&gt;
* SOAP::Lite&lt;br /&gt;
* Text::Iconv&lt;br /&gt;
* Try::Tiny&lt;br /&gt;
* UPnP::Common&lt;br /&gt;
* UPnP::ControlPoint&lt;br /&gt;
* URI::Escape&lt;br /&gt;
* WWW::Jawbone::Up&lt;br /&gt;
* Win32::SerialPort&lt;br /&gt;
* XML::LibXML&lt;br /&gt;
* XML::Parser::Lite&lt;br /&gt;
&lt;br /&gt;
[https://raw.githubusercontent.com/fhem/doc-wiki/master/DE/Howtos/fhem-cpan-modules.txt Liste als plain text], z.B. um sie bei einer automatisierten Installation verwenden zu können. Die Liste wurde mit &amp;lt;code&amp;gt;Perl::PrereqScanner&amp;lt;/code&amp;gt; aus dem &amp;lt;code&amp;gt;FHEM/&amp;lt;/code&amp;gt;-Verzeichnis erstellt, durch &amp;lt;code&amp;gt;Core::List&amp;lt;/code&amp;gt; gefiltert und mit &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; auf Nicht-CPAN-Module (z.B. &amp;lt;code&amp;gt;FHEM::Meta&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;DevIO&amp;lt;/code&amp;gt;) geprüft.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HOWTOS]] &lt;br /&gt;
[[Kategorie:Systemadministration]] &lt;br /&gt;
[[Kategorie:Perl]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=34238</id>
		<title>CPAN</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=34238"/>
		<updated>2020-11-16T09:13:43Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Wording&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= CPAN =&lt;br /&gt;
&lt;br /&gt;
Das CPAN, Comprehensive Perl Archive Network, ist ein weltweit verteiltes Netzwerk für Perl-Module, das seit 1995 besteht und aktuell etwa 200 000 Module umfasst.&lt;br /&gt;
&lt;br /&gt;
Siehe auch hier eine [https://www.cpan.org/modules/INSTALL.html Zusammenfassung des CPAN-Projektes].&lt;br /&gt;
&lt;br /&gt;
== Clients ==&lt;br /&gt;
&lt;br /&gt;
=== Plattformunabhängig ===&lt;br /&gt;
&lt;br /&gt;
Das CPAN bietet drei plattformunabhängige Clients an, von denen zwei hier beschrieben werden. Die &#039;&#039;Empfehlung&#039;&#039; ist, &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; zu nutzen.&lt;br /&gt;
&lt;br /&gt;
==== cpanminus ====&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/distribution/App-cpanminus/bin/cpanm cpanminus] (&amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt;) ist der bevorzugte Weg, wie CPAN-Pakete installiert werden sollten. cpan-minus ist, wie &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; ein CPAN-Paket, das aber auch für viele Betriebssystem als fertiges Paket portiert wurde.&lt;br /&gt;
&lt;br /&gt;
cpan-minus bietet einen [http://cpanmin.us/ Quickstart] an, der auf jedem System läuft, auf dem Perl installiert ist. Dazu muss folgender Befehl auf der Kommandozeile ausgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;curl -L https://cpanmin.us | perl - App::cpanminus&amp;lt;/pre&amp;gt;&lt;br /&gt;
Aus Sicherheitsgründen sollte vor Ausführung des Befehls überprüft werden, was unter [http://cpanmin.us/ cpanmin.us] zu finden ist, da ggf. Schadcode unbemerkt eingeschmuggelt werden könnte.&lt;br /&gt;
&lt;br /&gt;
Ist der Client &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; installiert, kann mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpanm Paket::Name&amp;lt;/pre&amp;gt;&lt;br /&gt;
ein Paket (in diesem Falle das nicht-existende Paket &amp;lt;code&amp;gt;Paket::Name&amp;lt;/code&amp;gt;) installiert werden. Die Option &amp;lt;code&amp;gt;--sudo&amp;lt;/code&amp;gt; sorgt dafür, dass cpanminus die Installation als Superuser versucht (ggf. muss ein Passwort eingegeben werden).&lt;br /&gt;
&lt;br /&gt;
==== Exkurs: cpan-outdated ====&lt;br /&gt;
&lt;br /&gt;
Das Paket [https://metacpan.org/pod/distribution/cpan-outdated/script/cpan-outdated &amp;lt;code&amp;gt;cpan-outdated&amp;lt;/code&amp;gt;] erzeugt eine cpanminus-kompatible Liste an CPAN-Paketen, die aktualisiert werden können, z.B.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ cpan-outdated &lt;br /&gt;
A/AN/ANDK/CPAN-2.27.tar.gz&lt;br /&gt;
L/LE/LEONT/Test-Harness-3.42.tar.gz&lt;br /&gt;
B/BI/BINGOS/Archive-Tar-2.36.tar.gz&lt;br /&gt;
T/TO/TODDR/autodie-2.32.tar.gz&lt;br /&gt;
R/RU/RURBAN/B-Debug-1.26.tar.gz&lt;br /&gt;
I/IL/ILMARI/bareword-filehandles-0.007.tar.gz&lt;br /&gt;
P/PJ/PJACKLAM/bignum-0.51.tar.gz&lt;br /&gt;
X/XS/XSAWYERX/Carp-1.50.tar.gz&lt;br /&gt;
L/LE/LEEJO/CGI-4.47.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Clone-0.45.tar.gz&lt;br /&gt;
M/ML/MLEHMANN/common-sense-3.75.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Bzip2-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Zlib-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/IO-Compress-2.093.tar.gz&lt;br /&gt;
H/HM/HMBRAND/Config-Perl-V-0.31.tgz&lt;br /&gt;
A/AT/ATOOMIC/TimeDate-2.33.tar.gz&lt;br /&gt;
P/PM/PMQS/DB_File-1.853.tar.gz&lt;br /&gt;
H/HU/HURRICUP/Devel-Camelcadedb-v2019.1.tar.gz&lt;br /&gt;
P/PJ/PJCJ/Devel-Cover-1.36.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Devel-PPPort-3.58.tar.gz&lt;br /&gt;
M/MS/MSHELOR/Digest-SHA-6.02.tar.gz&lt;br /&gt;
R/RJ/RJBS/Email-Sender-1.300034.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Sehr nützlich ist die Kombination aus cpanminus und cpan-outdated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan-outdated | cpanm --sudo&amp;lt;/pre&amp;gt;&lt;br /&gt;
Diese Befehlssequenz aktualisiert alle aktualisierbaren CPAN-Pakete mit Hilfe von cpanminus (als Superuser).&lt;br /&gt;
&lt;br /&gt;
==== cpan ====&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/CPAN &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;] ist der mit jeder Perl-Installation mitgelieferte Client für das CPAN und lässt sich entweder mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;perl -MCPAN -e shell&amp;lt;/pre&amp;gt;&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan&amp;lt;/pre&amp;gt;&lt;br /&gt;
starten. Es wird ein interaktiver Client gestartet; mit &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; kann eine sehr umfangreiche Hilfe aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Ein Modul lässt sich am einfachsten mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan install PAKET::NAME&amp;lt;/pre&amp;gt;&lt;br /&gt;
installieren (hier das nicht-existente Paket &amp;lt;code&amp;gt;PAKET::NAME&amp;lt;/code&amp;gt;). &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; eignet sich weniger gut um Module zu installieren oder zu aktualisieren, aber sehr gut um nach Paketen zu suchen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;i /JSON/&amp;lt;/pre&amp;gt;&lt;br /&gt;
findet jedes Paket, das die Zeichenkette &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; im Bereich Autor, Bundle, Distribution oder Modul enthält. Das sind meist viele Ergebnisse, aber liefert einen Überblick &amp;amp;quot;was geht&amp;amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß ist &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; recht störrisch in der Handhabung. Deshalb empfehle ich die Nutzung von cpanminus.&lt;br /&gt;
&lt;br /&gt;
=== OS-Paketmanager ===&lt;br /&gt;
&lt;br /&gt;
==== Debian und Derivate (Ubuntu, Raspbian, etc.) ====&lt;br /&gt;
&lt;br /&gt;
Vom Debian-Projekt werden viele, aber lange nicht alle, Pakete des CPAN auch als Pakete für den eingebauten Paketmanager &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt; [https://packages.debian.org/stable/perl/ bereitsgestellt]. Dort sind momentan etwa 4 000 Pakete verfügbar, d.h. rund 2% der im CPAN verfügbaren Pakete. Es ist nicht immer trivial, ein Paket zu finden. Ein einfacher Fall ist z.B. das Paket &amp;lt;code&amp;gt;Readonly&amp;lt;/code&amp;gt;, das über &amp;lt;code&amp;gt;cpanm Readonly&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;apt-get install libreadonly-perl&amp;lt;/code&amp;gt; installiert werden könnte. Im Allgemeinen kann man sagen, dass sich der Name des &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;-Paketes aus dem Prefix &amp;lt;code&amp;gt;lib&amp;lt;/code&amp;gt;, gefolgt vom Paketnamen in Kleinbuchstaben, bei dem die &amp;lt;code&amp;gt;::&amp;lt;/code&amp;gt; durch &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt; ersetzt wurden, und dem Suffix &amp;lt;code&amp;gt;-perl&amp;lt;/code&amp;gt; zusammensetzt:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! CPAN&lt;br /&gt;
! Debian-Paket&lt;br /&gt;
|-&lt;br /&gt;
| Rose::URI&lt;br /&gt;
| librose-uri-perl&lt;br /&gt;
|-&lt;br /&gt;
| Sah::Schemas::Rinci&lt;br /&gt;
| libsah-schemas-rinci-perl&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Kein Beispiel wäre vollständig ohne Ausnahme, z.B.:&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;libromana-perligata-perl&amp;lt;/code&amp;gt;] installiert das Perl-Paket [https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;Lingua::Romana::Perligata&amp;lt;/code&amp;gt;], müsste nach der selbstgewählten Konvention aber &amp;lt;code&amp;gt;liblingua-romana-perligata-perl&amp;lt;/code&amp;gt; heißen.&lt;br /&gt;
&lt;br /&gt;
Vorteilhaft ist, dass man die Pakete zusammen mit anderen Debian-Paketen automatisch auf dem aktuellen Stand halten kann, z.B. [https://wiki.debian.org/UnattendedUpgrades &amp;lt;code&amp;gt;unattended-upgrades&amp;lt;/code&amp;gt;] - man spart so eine doppelte Implementierung der Updates.&lt;br /&gt;
&lt;br /&gt;
Wiederum von Nachteil ist, dass man mit einer auf ein Release festgelegten Quelle irgendwann auch keine Updates der Perl-Pakete mehr erhält.&lt;br /&gt;
&lt;br /&gt;
==== SuSE Linux ====&lt;br /&gt;
&lt;br /&gt;
YaST bietet aktuell etwa 3 121 der rund 200 000 Pakete in [https://build.opensuse.org/project/show/devel:languages:perl &amp;lt;code&amp;gt;devel:languages:perl&amp;lt;/code&amp;gt;] an, dazu kommen noch einige Community-Pakete mit einer trivial nicht feststellbaren Anzahl an Paketen. Im Paket [https://build.opensuse.org/package/show/devel:languages:perl:CPAN-A/perl-App-cpanminus &amp;lt;code&amp;gt;perl-App-cpanminus&amp;lt;/code&amp;gt;] ist &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; enthalten.&lt;br /&gt;
&lt;br /&gt;
==== RedHat Linux ====&lt;br /&gt;
&lt;br /&gt;
==== MacOS ====&lt;br /&gt;
&lt;br /&gt;
Für MacOS gilt, dass das installierte Perl den &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;-Client und eine Auswahl an Module mitbringt. &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; lässt sich installieren und sollte auch der Weg der Wahl sein. Es ist außerdem möglich, Pakete über [https://www.macports.org/ MacPorts] zu installieren. MacPorts bietet noch weniger Pakete (aktuell 1 797 für Perl 5.26, 1 799 für Perl 5.28) als Debian.&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
&lt;br /&gt;
[https://www.activestate.com/products/perl/downloads/ ActiveState] bietet eine Perl-Distribution an, die bereits mit einigen Module, 214 bei [https://platform.activestate.com/ActiveState/ActivePerl-5.28 Perl 5.28], ausgeliefert wird.&lt;br /&gt;
&lt;br /&gt;
== Empfohlene Pakete ==&lt;br /&gt;
&lt;br /&gt;
Im FHEM-Umfeld werden aktuell rund 120 CPAN-Pakete (mit Sub-Paketen) eingesetzt die keine [https://www.perl.com/article/what-is-the-perl-core-/ Core-Module] sind und ggf. für ein FHEM-Modul [[Meta|nachinstalliert]] werden müssen:&lt;br /&gt;
&lt;br /&gt;
* Authen::OATH&lt;br /&gt;
* AutoLoader&lt;br /&gt;
* B&lt;br /&gt;
* Carp&lt;br /&gt;
* Color&lt;br /&gt;
* Compress::Zlib&lt;br /&gt;
* Convert::Base32&lt;br /&gt;
* Cpanel::JSON::XS&lt;br /&gt;
* Crypt::Argon2&lt;br /&gt;
* Crypt::CBC&lt;br /&gt;
* Crypt::Cipher::AES&lt;br /&gt;
* Crypt::ECB&lt;br /&gt;
* Crypt::Mode::CBC&lt;br /&gt;
* Crypt::MySQL&lt;br /&gt;
* Crypt::NaCl::Sodium&lt;br /&gt;
* Crypt::Rijndael&lt;br /&gt;
* Crypt::Rijndael_PP&lt;br /&gt;
* Crypt::URandom&lt;br /&gt;
* DBI&lt;br /&gt;
* DBI::Const::GetInfoType&lt;br /&gt;
* Data::Dumper&lt;br /&gt;
* Data::UUID&lt;br /&gt;
* Date::Parse&lt;br /&gt;
* DateTime&lt;br /&gt;
* Device::Firmata&lt;br /&gt;
* Device::Firmata::Base&lt;br /&gt;
* Device::Firmata::Constants&lt;br /&gt;
* Device::Firmata::Error&lt;br /&gt;
* Device::Firmata::Language&lt;br /&gt;
* Device::Firmata::Platform&lt;br /&gt;
* Device::Firmata::Protocol&lt;br /&gt;
* Device::SerialPort&lt;br /&gt;
* Device::USB&lt;br /&gt;
* Digest::CRC&lt;br /&gt;
* Digest::SHA1&lt;br /&gt;
* Encode::Detect::Detector&lt;br /&gt;
* Expect&lt;br /&gt;
* File::HomeDir&lt;br /&gt;
* HTML::Entities&lt;br /&gt;
* HTML::Parser&lt;br /&gt;
* HTTP::Cookies&lt;br /&gt;
* HTTP::Daemon&lt;br /&gt;
* HTTP::Headers&lt;br /&gt;
* HTTP::Request&lt;br /&gt;
* HTTP::Request::Common&lt;br /&gt;
* IO::Interface::Simple&lt;br /&gt;
* IO::Socket::Multicast&lt;br /&gt;
* IO::Socket::Multicast6&lt;br /&gt;
* IO::Socket::SSL&lt;br /&gt;
* IO::Socket::Timeout&lt;br /&gt;
* IO::String&lt;br /&gt;
* Image::ExifTool&lt;br /&gt;
* Image::LibRSVG&lt;br /&gt;
* Image::Size&lt;br /&gt;
* Inline&lt;br /&gt;
* JSON&lt;br /&gt;
* JSON::MaybeXS&lt;br /&gt;
* JSON::XS&lt;br /&gt;
* JSON::backportPP&lt;br /&gt;
* JsonMod::JSON::Path::Node&lt;br /&gt;
* LWP&lt;br /&gt;
* LWP::Simple&lt;br /&gt;
* LWP::UserAgent~6&lt;br /&gt;
* Linux::Inotify2&lt;br /&gt;
* LiquidCrystal&lt;br /&gt;
* Lirc::Client&lt;br /&gt;
* List::MoreUtils&lt;br /&gt;
* MIME::Lite&lt;br /&gt;
* MP3::Info&lt;br /&gt;
* MP3::Tag&lt;br /&gt;
* MP3::Tag::CDDB_File&lt;br /&gt;
* MP3::Tag::Cue&lt;br /&gt;
* MP3::Tag::File&lt;br /&gt;
* MP3::Tag::ID3v1&lt;br /&gt;
* MP3::Tag::ID3v2&lt;br /&gt;
* MP3::Tag::ImageExifTool&lt;br /&gt;
* MP3::Tag::ImageSize&lt;br /&gt;
* MP3::Tag::Inf&lt;br /&gt;
* MP3::Tag::LastResort&lt;br /&gt;
* MP3::Tag::ParseData&lt;br /&gt;
* Mail::IMAPClient&lt;br /&gt;
* Mojolicious~5.54&lt;br /&gt;
* Net::Address::IP::Local&lt;br /&gt;
* Net::Bonjour&lt;br /&gt;
* Net::FTPSSL&lt;br /&gt;
* Net::Jabber&lt;br /&gt;
* Net::MQTT::Constants&lt;br /&gt;
* Net::MQTT::Message&lt;br /&gt;
* Net::MQTT::Message::JustMessageId&lt;br /&gt;
* Net::Rendezvous&lt;br /&gt;
* Net::SIP&lt;br /&gt;
* Net::SIP::Packet&lt;br /&gt;
* Net::SMTP::SSL&lt;br /&gt;
* Net::Telnet&lt;br /&gt;
* Net::UPnP::AV::MediaRenderer&lt;br /&gt;
* Net::UPnP::AV::MediaServer&lt;br /&gt;
* Net::UPnP::ControlPoint&lt;br /&gt;
* Net::UPnP::Device&lt;br /&gt;
* Net::UPnP::Service&lt;br /&gt;
* Net::XMPP::Namespaces&lt;br /&gt;
* Nmap::Parser&lt;br /&gt;
* Path::Tiny&lt;br /&gt;
* Paws::Polly&lt;br /&gt;
* Perl::PrereqScanner::NotQuiteLite&lt;br /&gt;
* RPC::XML::Client&lt;br /&gt;
* RPC::XML::Server&lt;br /&gt;
* RiveScript&lt;br /&gt;
* SOAP::Lite&lt;br /&gt;
* Text::Iconv&lt;br /&gt;
* Try::Tiny&lt;br /&gt;
* UPnP::Common&lt;br /&gt;
* UPnP::ControlPoint&lt;br /&gt;
* URI::Escape&lt;br /&gt;
* WWW::Jawbone::Up&lt;br /&gt;
* Win32::SerialPort&lt;br /&gt;
* XML::LibXML&lt;br /&gt;
* XML::Parser::Lite&lt;br /&gt;
&lt;br /&gt;
[https://raw.githubusercontent.com/fhem/doc-wiki/master/DE/Howtos/fhem-cpan-modules.txt Liste als plain text], z.B. um sie bei einer automatisierten Installation verwenden zu können. Die Liste wurde mit &amp;lt;code&amp;gt;Perl::PrereqScanner&amp;lt;/code&amp;gt; aus dem &amp;lt;code&amp;gt;FHEM/&amp;lt;/code&amp;gt;-Verzeichnis erstellt, durch &amp;lt;code&amp;gt;Core::List&amp;lt;/code&amp;gt; gefiltert und mit &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; auf Nicht-CPAN-Module (z.B. &amp;lt;code&amp;gt;FHEM::Meta&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;DevIO&amp;lt;/code&amp;gt;) geprüft.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HOWTOS]] &lt;br /&gt;
[[Kategorie:Systemadministration]] &lt;br /&gt;
[[Kategorie:Perl]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=HM-CFG-USB_USB_Konfigurations-Adapter&amp;diff=33839</id>
		<title>HM-CFG-USB USB Konfigurations-Adapter</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=HM-CFG-USB_USB_Konfigurations-Adapter&amp;diff=33839"/>
		<updated>2020-09-03T14:47:55Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Hardware&lt;br /&gt;
|Bild=HM-CFG-USB-2.jpg&lt;br /&gt;
|Bildbeschreibung=HomeMatic USB Konfigurationsadapter (Version 2)&lt;br /&gt;
|HWProtocol=HomeMatic &lt;br /&gt;
|HWType=Interface/Gateway&lt;br /&gt;
|HWCategory=HomeMatic&lt;br /&gt;
|HWComm=868,3 MHz&lt;br /&gt;
|HWChannels=&lt;br /&gt;
|HWVoltage=5 V&lt;br /&gt;
|HWPowerConsumption=&lt;br /&gt;
|HWPoweredBy=USB-Bus&lt;br /&gt;
|HWSize=V1: 40 x 90 x 25 mm&amp;lt;br /&amp;gt;V2: 28 x 84 x 11,5 mm&lt;br /&gt;
|HWDeviceFHEM=[http://fhem.de/commandref.html#CUL_HM CUL_HM]&lt;br /&gt;
&amp;lt;!-- |ModOwner=  --&amp;gt;&lt;br /&gt;
|HWManufacturer=eQ-3&lt;br /&gt;
}}&lt;br /&gt;
Der [[HomeMatic]] &#039;&#039;&#039;USB Konfigurations-Adapter&#039;&#039;&#039; ist ein USB-Stick, der außer zur Konfiguration von HomeMatic-Komponenten auch als [[Interface]] zwischen FHEM und HomeMatic-Geräten benutzt werden kann. Er existiert in zwei Versionen: der älteren HM-CFG-USB und der neueren HM-CFG-USB2. Die folgenden Beschreibungen gelten für beide Versionen, es sei denn, es ist ausdrücklich eine spezifische Version genannt.&lt;br /&gt;
&lt;br /&gt;
== Einbindung in FHEM ==&lt;br /&gt;
Im FHEM-Forum wird die Einbindung als Interface in diesem {{Link2Forum|Topic=13071}} beschrieben und diskutiert. Im {{Link2Forum|Topic=13071|Message=79872|LinkText=Eröffnungsbeitrag}} wird eine gut funktionierende HMLAN-Emulationssoftware [https://git.zerfleddert.de/cgi-bin/gitweb.cgi/hmcfgusb hmland] von ihrem Entwickler vorgestellt, um den HM-CFG-USB in FHEM zu integrieren. Die HMLAN-Emulationssoftware muss zunächst kompiliert und installiert werden. Anschließend wird der HM-CFG-USB (üblicherweise auf localhost) genau wie [[HM-CFG-LAN LAN Konfigurations-Adapter|HMLAN]] in FHEM eingebunden. &lt;br /&gt;
&lt;br /&gt;
=== Einrichtung unter Linux ===&lt;br /&gt;
Die Schritte zur Kompilierung und Installation hat der hmland-Entwickler sowohl auf der [https://git.zerfleddert.de/cgi-bin/gitweb.cgi/hmcfgusb hmland-Internetseite] in Englisch (kurz) als auch im oben genannten {{Link2Forum|Topic=13071|Message=79872|LinkText=Eröffnungsbeitrag}} in Deutsch (ausführlich) dargestellt. Die dort gemachten Angaben werden auch bei Bedarf aktualisiert und sind deshalb der beste Anlaufpunkt für Kompilierung und Installation. &lt;br /&gt;
&lt;br /&gt;
{{Randnotiz|RNTyp=Info|RNText=&#039;&#039;&#039;Skript zur Kompletteinrichtung unter Linux&#039;&#039;&#039;&lt;br /&gt;
Dieser {{Link2Forum|Topic=13071|Message=190887|LinkText=Bericht}} im Forum stellt ein Script vor, das &#039;&#039;hmland&#039;&#039; herunterlädt, übersetzt (kompiliert), installiert sowie ein init-Script anlegt, so dass fast keine manuellen Eingriffe mehr notwendig sind.}}&lt;br /&gt;
Die nachfolgenden Angaben in diesem Abschnitt sind rein zu Informationszwecken (noch) enthalten: &lt;br /&gt;
&lt;br /&gt;
Zunächst muss die HMLAN-Emulationssoftware kompiliert werden. Analog zu [https://git.zerfleddert.de/cgi-bin/gitweb.cgi/hmcfgusb dieser Beschreibung] ist die Vorgehensweise die folgende (in Debian/Ubuntu/Raspbian):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 cd /opt/&lt;br /&gt;
 apt-get install build-essential libusb-1.0-0-dev make gcc git&lt;br /&gt;
 git clone git://git.zerfleddert.de/hmcfgusb&lt;br /&gt;
 cd hmcfgusb&lt;br /&gt;
 make&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach kann der Dienst (zu Testzwecken sind Debugging-Ausgaben mit &amp;lt;code&amp;gt;-D&amp;lt;/code&amp;gt; aktiviert) gestartet werden:&lt;br /&gt;
:&amp;lt;code&amp;gt; /opt/hmcfgusb/hmland -p 1234 -D&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Start als Daemon ====&lt;br /&gt;
Um &#039;&#039;hmland&#039;&#039; automatisch als Daemon bei &#039;&#039;&#039;init.d Systemen&#039;&#039;&#039; zu starten, kann ein init-Script genutzt werden. Die Quellen von &#039;&#039;hmland&#039;&#039; enthalten ein solches Script im &amp;lt;code&amp;gt;debian/&amp;lt;/code&amp;gt; Unterverzeichnis:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cp /opt/hmcfgusb/debian/hmland.init /etc/init.d/hmland&lt;br /&gt;
cp /opt/hmcfgusb/debian/hmland.default /etc/default/hmland&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einstellungen, beispielsweise der Port, auf dem &#039;&#039;hmland&#039;&#039; hört, können (und sollten) in der Datei &amp;lt;code&amp;gt;/etc/default/hmland&amp;lt;/code&amp;gt; vorgenommen werden. Wichtig: Wenn diese Anleitung befolgt wurde, muss in der Datei &amp;lt;code&amp;gt;/etc/init.d/hmland&amp;lt;/code&amp;gt; die folgende Zeile wie folgt angepasst werden (&amp;lt;code&amp;gt;/hm&amp;lt;/code&amp;gt; aus dem Pfad entfernen), damit der automatische Start des Daemon klappt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
DAEMON=/opt/hmcfgusb/$NAME # Introduce the server&#039;s location here&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die kopierte Datei mit &amp;lt;code&amp;gt;chmod 755 /etc/init.d/hmland&amp;lt;/code&amp;gt; ausführbar machen, anschließend kann &#039;&#039;hmland&#039;&#039; mit folgendem Befehl gestartet werden:&lt;br /&gt;
:&amp;lt;code&amp;gt;/etc/init.d/hmland start&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Start mit systemd ====&lt;br /&gt;
Bei Distributionen, die &#039;&#039;&#039;systemd&#039;&#039;&#039; einsetzen (z.B. Debian Stretch) kann folgende Konfigurationsdatei verwendet werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Homematic LAN Adapter service&lt;br /&gt;
After=network.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
ExecStart=/opt/hmcfgusb/hmland -p 1234&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei muss dann natürlich der Port (1234) an die eigene Konfiguration angepasst werden und auch der Pfad wo sich der &amp;lt;Code&amp;gt; hmland&amp;lt;/code&amp;gt; befindet, wenn man sich an oben stehendem Beispiel orientiert wäre das dann &amp;lt;Code&amp;gt;/opt/hmcfgusb/&amp;lt;/code&amp;gt;&lt;br /&gt;
Diese Datei muss dann als &amp;lt;Code&amp;gt;hmland.service&amp;lt;/code&amp;gt; unter &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;/etc/systemd/system&amp;lt;/syntaxhighlight&amp;gt; abgelegt werden.&lt;br /&gt;
Nun muss einmalig der Befehl&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;systemctl daemon-reload&amp;lt;/syntaxhighlight&amp;gt; ausgeführt werden damit die neuen Dateien eingelesen werden.&lt;br /&gt;
Mit dem Befehl &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;systemctl enable hmland&amp;lt;/syntaxhighlight&amp;gt; wird dafür gesorgt, dass bei einem Systemstart hmland automatisch gestartet wird&lt;br /&gt;
Mit  &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;systemctl status hmland &amp;lt;/syntaxhighlight&amp;gt; kann dann noch geprüft werden ob der Service läuft&lt;br /&gt;
&lt;br /&gt;
==== Start mit upstart ====&lt;br /&gt;
Bei Distributionen, die &#039;&#039;&#039;Upstart&#039;&#039;&#039; einsetzen (z.B. xbian) kann folgende Konfigurationsdatei verwendet werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# HMLAND&lt;br /&gt;
&lt;br /&gt;
description     &amp;quot;hmland&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start on starting fhem&lt;br /&gt;
stop on stopped fhem&lt;br /&gt;
&lt;br /&gt;
respawn&lt;br /&gt;
expect fork&lt;br /&gt;
&lt;br /&gt;
chdir /opt/hmcfgusb&lt;br /&gt;
exec /opt/hmcfgusb/hmland -d -l 127.0.0.1 -p 1234&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Datei sollte als &amp;lt;code&amp;gt;/etc/init/hmland.conf&amp;lt;/code&amp;gt; angelegt werden. Mit dem Befehl&lt;br /&gt;
:&amp;lt;code&amp;gt;initctl reload-configuration &amp;lt;/code&amp;gt;&lt;br /&gt;
wird Upstart angewiesen, seine Konfiguration erneut einzulesen. Danach kann der Dienst &#039;&#039;hmland&#039;&#039; mit&lt;br /&gt;
:&amp;lt;code&amp;gt;service hmland start &amp;lt;/code&amp;gt;&lt;br /&gt;
gestartet werden. &amp;lt;code&amp;gt;hmland&amp;lt;/code&amp;gt; wird jetzt immer vor FHEM gestartet und nach FHEM beendet.&lt;br /&gt;
&lt;br /&gt;
==== Start über FHEM Startskript ====&lt;br /&gt;
Ausprobiert auf einem BBB mit Debian, eigentlich ist das alles von Betateilchen:&lt;br /&gt;
&lt;br /&gt;
Zunächst hmland kompilieren wie oben beschrieben, bis zum make. Das muss erfolgreich durchgelaufen sein.&lt;br /&gt;
&lt;br /&gt;
Dann geht es weiter:&lt;br /&gt;
:&amp;lt;code&amp;gt;sudo cp hmcfgusb.rules /etc/udev/rules.d/ &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jetzt das FHEM Startskript anpassen (in den Blöcken &#039;start&#039; und &#039;stop&#039; muss quasi nur jeweils 1 Zeile eingefügt werden:&lt;br /&gt;
&lt;br /&gt;
Damit editiert man das FHEM Startskript:&lt;br /&gt;
:&amp;lt;code&amp;gt;sudo nano /etc/init.d/fhem &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so sollten die Blöcke anschließend aussehen (bitte nur jeweils die Zeile mit hmland einfügen)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 &#039;start&#039;)&lt;br /&gt;
        echo &amp;quot;Starting fhem...&amp;quot;&lt;br /&gt;
        /opt/hmcfgusb/hmland -d -p 1234&lt;br /&gt;
        perl fhem.pl fhem.cfg&lt;br /&gt;
        RETVAL=$?&lt;br /&gt;
        ;;&lt;br /&gt;
&lt;br /&gt;
 &#039;stop&#039;)&lt;br /&gt;
        echo &amp;quot;Stopping fhem...&amp;quot;&lt;br /&gt;
        perl fhem.pl $port &amp;quot;shutdown&amp;quot;&lt;br /&gt;
        RETVAL=$?&lt;br /&gt;
        pkill hmland&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So wird hmland vor FHEM gestartet und nach FHEM beendet. Letztlich erspart es Probleme mit den diversen Startskripten und ihren Rechten.&lt;br /&gt;
&lt;br /&gt;
Es dauert nach dem Start von FHEM noch einige Sekunden, bis hmland fertig geladen ist. In dieser Zeit kann es zu fehlerhaften Einträgen im Logfile kommen.&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung auf Synology DiskStations ===&lt;br /&gt;
Packages für DSM5.2 finden sich hier:&lt;br /&gt;
https://github.com/mkunzmann/spksrc/releases/tag/0.101-3&lt;br /&gt;
&lt;br /&gt;
Welches Package für welche DS kann man hier sehen:&lt;br /&gt;
https://github.com/SynoCommunity/spksrc/wiki/Architecture-per-Synology-model&lt;br /&gt;
&lt;br /&gt;
Einfach das passende Package installieren und dann kann man den hmland über den Synology Package-Manager starten und stoppen. Während der Installation kann man den Port für hmland festlegen. Bitte einen Port &amp;gt; 1024 wählen, da der hmland nicht als root läuft. Außerdem kann ein Logfile angegeben werden. Hier am besten eine Datei auf einem USB Stick angeben die für jedermann schreibbar sein muss. Damit sollten die Platten nach wie vor in den Standby gehen.&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung unter Mac OS X ===&lt;br /&gt;
Wie unter Linux braucht man die HMLAN-Emulationssoftware hmland, die man aus Quelltexten erstellen muss. Dazu muss man die Bibliothek libusb installieren, entweder mit einem der Paketmanager wie Fink, MacPorts oder Homebrew oder direkt aus den Quellentexten (Beispiel: &amp;quot;fink install libusb1-shlibs libusb1&amp;quot;). Hat man wie bei Linux das Quelltextarchiv für hmland heruntergeladen und ausgepackt, müssen die Dateien Makefile und hmcfgusb.c angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Im Makefile muss man den Pfad zur libusb anpassen. Hat man libusb mit fink installiert, muss man, &amp;quot;/opt/local/&amp;quot; durch &amp;quot;/sw/&amp;quot; bei den CFLAGS und den LDFLAGS ersetzen und&lt;br /&gt;
das &amp;quot;-lrt&amp;quot; aus den LDLIBS entfernen. Die Library librt gibt es bei Mac OS X nicht und wird anscheinend auch nicht gebraucht. (Stimmt das eigentlich?)&lt;br /&gt;
&lt;br /&gt;
In der Datei hmcfgusb.c muss man die Zeilen 130-134 mit dem Aufruf libusb_detach_kernel_driver auskommentieren oder löschen. Der geht nicht auf Mac OS X.&lt;br /&gt;
&lt;br /&gt;
Nach den Änderungen in den zwei Dateien, kann man wie bei Linux den Dämon hmland mit dem Kommando &amp;quot;make&amp;quot; erzeugen und mit &amp;quot;./hmland&amp;quot; ausführen. Automatisches Starten beim Booten mit launchd ist noch nicht probiert.&lt;br /&gt;
&lt;br /&gt;
Beim Start von hmland sollte man folgende Fehlermeldung in einer Endlos-Schleife erhalten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Datum Zeit: Client 127.0.0.1 connected!&lt;br /&gt;
Can&#039;t claim interface: Access denied (insufficient permissions)&lt;br /&gt;
Can&#039;t find/open hmcfgusb!&lt;br /&gt;
Datum Zeit: Connection to 127.0.0.1 closed!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch ein Start von hmland mit Superuser-Rechten ändert daran nichts. Damit das claim interface klappt, muss man eine codeless kext in den Ordner /Library/Extensions legen. Ich habe dieses (http://mspdebug.sourceforge.net/misc/ex430rf2500-kext.zip) herunter geladen. Damit es funktioniert, muss man aber in der Datei Info.plist des Bundle die Properties idProduct und idVendor ändern, entweder mit dem Property List Editor oder einem anderen Texteditor. Die beiden Properties sind etwas versteckt bei Information Property List → IOKitPersonalities → ComIntf. Bei DebugIntf und DeviceDriver scheint man es nicht ändern zu müssen, aber schaden kann es nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
idProduct: 49167&lt;br /&gt;
idVendor: 6943&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Rechte des kext-Bundles müssen auch noch gesetzt werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
  chmod -R 755 ex430rf2500.kext&lt;br /&gt;
  chown -R root:wheel ex430rf2500.kext&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach die Datei ex430rf2500.kext in den Ordner /Library/Extensions legen und hmland sollte dann funktionieren.&lt;br /&gt;
&lt;br /&gt;
Es kann sein, dass ab Mac OS X 10.9 der Trick mit dem codeless kext nicht mehr funktioniert, aber noch ist das nicht getestet oder bestätigt. Langfristig kann man vielleicht auch eine kext mit einem Treiber für den HM-CFG-USB USB erstellen&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung unter Windows ===&lt;br /&gt;
Bei der Einrichtung und vermutlich auch dem Betrieb unter Windows 8.1 sind wegen der erweiterten Energieverwaltungsfunktionen die von eQ-3 [http://www.eq-3.de/Downloads/eq3/pdf_FAQ/Funk-Konfigurationsdapter-USB_Windos_8.1.pdf zusammengestellten Tipps] zu befolgen.&lt;br /&gt;
&lt;br /&gt;
=== Definition(en) in der FHEM-Konfiguration ===&lt;br /&gt;
In der FHEM [[Konfiguration]] muss noch, sofern/sobald der &#039;&#039;hmland&#039;&#039; läuft, das Device eingerichtet werden mit den folgenden Anweisungen:&lt;br /&gt;
:&amp;lt;code&amp;gt;define &#039;&#039;&#039;hmusb&#039;&#039;&#039; HMLAN 127.0.0.1:1234 &amp;lt;/code&amp;gt;&lt;br /&gt;
wobei &#039;&#039;&#039;hmusb&#039;&#039;&#039; der frei wählbare Devicename ist. Anschließend sollte bzw. muss noch mit&lt;br /&gt;
:&amp;lt;code&amp;gt;attr &#039;&#039;&#039;hmusb&#039;&#039;&#039; hmId &amp;lt;&#039;&#039;&#039;hmId&#039;&#039;&#039;&amp;gt; &amp;lt;/code&amp;gt;&lt;br /&gt;
eine &#039;&#039;&#039;hmId&#039;&#039;&#039; zugeordnet werden (dabei bitte auch die Hinweise und Regeln beachten, die im Zusammenhang mit der [[Virtueller Controller VCCU|VCCU]] beschrieben sind!&lt;br /&gt;
&lt;br /&gt;
== Firmware Update ==&lt;br /&gt;
Der Firmware Update (unter Linux) ist ebenfalls auf der [https://git.zerfleddert.de/cgi-bin/gitweb.cgi/hmcfgusb hmland-Internetseite] beschrieben. Auch die letzte bekannte Firmware-Version (0.967) steht dort zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
== Bekannte Probleme ==&lt;br /&gt;
=== Verbindung zu neueren hmland-Versionen nicht stabil ===&lt;br /&gt;
Seit Version 0.100 meldet sich die HMLAN-Emulationssoftware als USB-Interface bei FHEM. Ältere FHEM-Versionen (vor dem 19.6.2015) brechen deshalb die Verbindung ab, da sie nur ein LAN-Interface erwarten.&lt;br /&gt;
&lt;br /&gt;
Lösung: Kommandozeilenparameter &amp;lt;code&amp;gt;-I&amp;lt;/code&amp;gt; dem hmland-Aufruf hinzufügen, dann meldet sich dieser wieder als LAN-Interface.&lt;br /&gt;
&lt;br /&gt;
=== Stick nicht (mehr) ansprechbar ===&lt;br /&gt;
Zitat aus dem {{Link2Forum|Topic=32502|Message=249122|LinkText=FHEM-Forum}}: &lt;br /&gt;
:&#039;&#039;... befürchte ich, dass dein Stick das Zeitliche gesegnet hat. Machen die Dinger leider sehr gerne... Ganz besonders beim Modus-Wechsel vom 10k- in den 100k-Modus, wenn man bei irgendeinem Device ein Firmwareupdate durchführt. &amp;lt;br /&amp;gt;Die gute Nachricht ist, dass der Fehler bei sämtlichen Händlern bekannt ist und anstandslos getauscht wird.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Raspberry Pi ===&lt;br /&gt;
Der USB-Stack am Raspberry Pi ist für viele Probleme verantwortlich. Daher sieht man öfter Fehlermeldungen:&lt;br /&gt;
:&amp;lt;code&amp;gt;usb-transfer took more than 100ms (1039ms), this may lead to timing problems!&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da das Timing bei HomeMatic wichtig ist führt das zu vielen Retransmits und zu unzuverlässigen Aktoren. Als Workaround kann man den USB-Stack auf die deutlich langsamere Version 1.1 stellen. Dazu fügt man folgenden Text am Anfang der Datei /boot/cmdline.txt ein:&lt;br /&gt;
:&amp;lt;code&amp;gt;dwc_otg.speed=1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Weitergehende Informationen ==&lt;br /&gt;
Es sind zwei Versionen des HM-CFG-USB im Umlauf:&lt;br /&gt;
{{Randnotiz|RNTyp=r|RNText=Stand März 2016 ist allem Anschein nach kein HM-CFG-USB mehr im ELV Programm enthalten!}}&lt;br /&gt;
* HM-CFG-USB-2: die aktuelle Version; Kennzeichen dieser Version: &lt;br /&gt;
** Größe: 28 x 84 x 11,5&amp;amp;nbsp;mm&lt;br /&gt;
** Gewicht: 18&amp;amp;nbsp;g&lt;br /&gt;
** Antenne innenliegend&lt;br /&gt;
* HM-CFG-USB: Vorgängerversion; Stand 12/2013 noch Restbestände im Handel verfügbar. Dokumentation ([http://files.voelkner.de/625000-649999/646462-an-01-ml-HM_Konfigurationsadapter_CFG_USB_de_en.pdf Völkner]); Kennzeichen:&lt;br /&gt;
** Anschluss per separatem USB-Kabel&lt;br /&gt;
** abstehende Stabantenne&lt;br /&gt;
** Größe: 40 x 90 x 25&amp;amp;nbsp;mm&lt;br /&gt;
** Gewicht: 45&amp;amp;nbsp;g&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* Bedienungsanleitung [http://www.eq-3.de/Downloads/eq3/pdf_produkte/HM-CFG-USB-2_-UM-eQ-3-150129-web.pdf HM-CFG-USB-2, PDF]&lt;br /&gt;
* FHEM-Forums {{Link2Forum|Topic=13071}}: HomeMatic USB Konfigurations-Adapter (HM-CFG-USB) in FHEM nutzen&lt;br /&gt;
* [http://www.eq-3.de/produkt-detail-zentralen-und-gateways/items/homematic-funk-konfigurationsadapter-usb.html eQ-3 Produktseite] zum &amp;quot;HomeMatic Funk-Konfigurationsadapter USB&amp;quot;; Downloads, technische Daten, etc.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HomeMatic Components]]&lt;br /&gt;
[[Kategorie:Interfaces]]&lt;br /&gt;
[[Kategorie:OSX]]&lt;br /&gt;
[[Kategorie:868MHz]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=MQTT&amp;diff=33684</id>
		<title>MQTT</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=MQTT&amp;diff=33684"/>
		<updated>2020-08-17T21:43:51Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Fixed perl packages&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MQTT ist ein Protokoll (&amp;quot;Message Queue Telemetry Transport&amp;quot;), mit dem Daten und Befehle zwischen verschiedenen Geräten ausgetauscht werden. Die Kommunikation erfolgt dabei über einen zentralen MQTT-Server, in alter Nomenklatur auch &#039;&#039;Broker&#039;&#039; genannt.&lt;br /&gt;
&lt;br /&gt;
MQTT wurde entwickelt, um möglichst effizient, sicher und mit wenig Datenlast zu kommunizieren. MQTT ist nachrichtenorientiert, daher muss ein Client nicht beständig beim Server anfragen, ob neue Daten vorliegen. Heute findet sich MQTT vor allem im Bereich des &#039;&#039;Internet of Things&#039;&#039; (IoT). MQTT kann leicht mit FHEM verbunden werden, ohne dass dabei größerer CPU- oder Datenverbrauch entsteht. &lt;br /&gt;
&lt;br /&gt;
== Eine sehr kurze Einführung in MQTT ==&lt;br /&gt;
Die folgende Einführung kann eine vollwertige Einleitung wie beispielsweise [https://github.com/mqtt/mqtt.github.io/wiki diese Wikieinträge] nicht ersetzen. &lt;br /&gt;
&lt;br /&gt;
Bei MQTT findet die nachrichtenbasierte Kommunikation zwischen einzelnen Teilnehmern&amp;lt;ref&amp;gt;Teilnehmer in diesem Sinne kann ein Stück Hardware mit einer MQTT-fähigen firmware sein, ein auf einem Computer laufendes Script (einschließlich eines MQTT-Server-Dienstes wie &#039;&#039;mosquitto&#039;&#039; oder &#039;&#039;MQTT2_SERVER&#039;&#039;, kurz: alles mögliche sein. Dadurch kann auch ein einzelner Computer unter mehreren ClientID&#039;s am MQTT-Datenaustausch beteiligt sein.&amp;lt;/ref&amp;gt; in der Regel nicht direkt statt. Stattdessen werden alle Nachrichten von einem Teilnehmer an einen Serverdienst, den MQTT-Server (früher &#039;&#039;Broker&#039;&#039; genannt) übergeben, der dann dafür sorgt, dass die Nachricht an alle (berechtigten) anderen Teilnehmer verteilt wird, die sich für derartige Nachrichten &amp;quot;interessieren&amp;quot;. Wenn also ein Teilnehmer ohne Server-Funktion (Client) Daten von einem bestimmten anderen Teilnehmer (anderer Client) empfangen will, muss es vorher dem MQTT-Server (Broker) mitteilen, dass er die Nachrichten dieses anderen Teilnehmers abonniert (deshalb wird dieser Vorgang als &#039;&#039;subscribe&#039;&#039; bezeichnet). Im IoT ist besonders interessant, dass Sender und Empfänger von Nachrichten durch den MQTT-Server vollständig entkoppelt werden können - jemand, der Daten bereit stellt, muss sich also nicht darum kümmern, wer diese Daten empfängt&amp;lt;ref&amp;gt;Aufgrund dieser Funktionsweise sollte allerdings darauf geachtet werden, die Möglichkeiten des jeweiligen Servers zur Sicherung der Daten gegen unberechtigten Zugriff zu nutzen, insbesondere wenn die Art der Daten oder die sich hierdurch ergebenden Möglichkeiten, z.B. Schaltvorgänge in der realen Welt auszulösen, dies notwendig macht!&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Eine Nachricht besteht im Wesentlichen aus den folgenden Elementen:&lt;br /&gt;
*ClientID -  das ist die Kennung des Senders einer Nachricht&amp;lt;ref&amp;gt;Diese kann sich bei der Weitergabe der Nachricht ändern: Zunächst sendet ein Client eine Nachricht unter seiner ClientID, der MQTT-Server wird diese dann in der Regel durch seine Kennung ersetzten, wenn er die Nachricht an einen Abonnenten - der auch ein weiterer MQTT-Server sein kann - weitergibt.&amp;lt;/ref&amp;gt;&lt;br /&gt;
*Topic - das ist die Adresse, an die eine Nachricht gesendet wird, bzw. von wo sie abgeholt werden kann (so ähnlich wie ein Postfach in der realen Welt). Topics sind einfache Strings, die mit Schrägstrichen getrennt werden (keine Leerzeichen und nur sehr wenige Sonderzeichen erlaubt). Ein Topic könnte beispielhaft so lauten: &amp;lt;code&amp;gt;zuHause/1OG/Kueche/Licht/state&amp;lt;/code&amp;gt;. Diese Topics beinhalten also eine Hierarchie der Objekte - hier im Beispiel sind sie zuerst danach sortiert, ob sie sich zu Haus befinden, dann wird nach Stockwerken sortiert und im ersten Stock schaut man auf die Küche sowie das dort vorhandene Licht.  &lt;br /&gt;
*Payload - das ist der Inhalt der Nachricht, oft handelt es sich um Befehle oder Daten.&lt;br /&gt;
*Quality of Service - soll geprüft werden, ob die Nachricht zugestellt wurde und wenn ja, mit welcher &amp;quot;Tiefe&amp;quot;?&lt;br /&gt;
*Retained Message. &lt;br /&gt;
Details bitte in der oben genannten Einführung nachlesen.&lt;br /&gt;
&lt;br /&gt;
MQTT kommuniziert üblicherweise über Port 1883, es können aber unter derselben Netzwerkadresse an unterschiedlichen Ports auch mehrere Serverdienste bereitstehen. &lt;br /&gt;
&lt;br /&gt;
== Installation in FHEM ==&lt;br /&gt;
Um MQTT in FHEM zu nutzen, benötigt man (mindestens) einen MQTT-Server.  Es gibt zwei Möglichkeiten: Man kann FHEM-externe Server-Software (oder auch einen oder mehrere im Internet bereitstehende MQTT-Server) verwenden oder man kann die MQTT-Serverkomponente aktivieren, die mit {{Link2CmdRef|Anker=MQTT2_SERVER|Lang=en|Label=MQTT2_SERVER}} in FHEM direkt bereitsteht. Hier werden kurz beide Installationswege erläutert, zwingend ist nur einer, da eben mindestens ein MQTT-Serverdienst aktiv sein muß.&lt;br /&gt;
&lt;br /&gt;
Die nachfolgenden Schaubilder zeigen schematisch die in FHEM zur Verfügung stehenden Wege der Einbindung von Hard- und/oder Softwarekomponenten, die über das MQTT-Protokoll Daten austauschen.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Datei:Mqtt2 server.png|Datenaustausch mit MQTT-Geräten, wenn MQTT2_SERVER als internem MQTT-Serverdienst verwendet wird&lt;br /&gt;
Datei:Mqtt2 client v extern server.png|Datenaustausch mit MQTT-Geräten, wenn MQTT2_CLIENT iVm. mosquitto als externem MQTT-Serverdienst verwendet wird&lt;br /&gt;
Datei:00 mqtt pm.png|Datenaustausch mit MQTT-Geräten, wenn das Modul &#039;&#039;MQTT&#039;&#039; (00_MQTT.pm) iVm. mosquitto als externem MQTT-Serverdienst verwendet wird&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
=== FHEM als MQTT-Server ===&lt;br /&gt;
Die mit dem Modul {{Link2CmdRef|Anker=MQTT2_SERVER|Lang=en|Label=MQTT2_SERVER}} bereitstehende Serverkomponente kann z.B. wie folgt aktiviert werden:&lt;br /&gt;
 defmod myBroker MQTT2_SERVER 1883 global&lt;br /&gt;
Dieses [[Gerät]] übernimmt dann die Kommunikation mit den externen Clients (und wird von diesen behandelt, wie jeder andere MQTT-Server auch&amp;lt;ref&amp;gt;Bitte beachten Sie, dass (Stand: Juni 2019) MQTT2_SERVER nicht alle features des MQTT-Protokolls unterstützt.&amp;lt;/ref&amp;gt;) und verteilt die eingehenden Nachrichten als IO-Device&amp;lt;ref&amp;gt;im Sinne des [[DevelopmentModuleIntro#Zweistufiges Modell für Module|2-stufigen Modulkonzepts]]&amp;lt;/ref&amp;gt; für die Client-Module [[MQTT2_DEVICE]]&amp;lt;ref&amp;gt;Die Zahl 2 in den Modulnamen verweist nur darauf, dass es sich um eine neuere Modulfamilie handelt; die Kommunikation mit den externen Komponenten unterscheidet sich nicht zu den älteren Modulen, die vor dem Jahr 2018 genutzt werden konnten.&amp;lt;/ref&amp;gt; und {{Link2CmdRef|Anker=MQTT_GENERIC_BRIDGE|Lang=de|Label=MQTT_GENERIC_BRIDGE}}.&lt;br /&gt;
Ein weiterer Vorteil dieser Lösung besteht darin, dass man ein MQTT2_SERVER-Device mit Hilfe von [[allowed]] absichern kann, was auch SSL-verschlüsselte Kommunikation ermöglicht. &#039;&#039;&#039;Hinweis:&#039;&#039;&#039; In diesem Fall muss User bzw. Passwort auch in den entsprechenden Geräten eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|Wenn Sie beabsichtigen, diese Variante zu verwenden, sollten Sie als nächstes die [[MQTT2-Module - Praxisbeispiele|Praxisbeispiele zu den MQTT2-Modulen]] lesen, und ggf. später wieder hierher zurückkehren. Dort findet sich auch ein Abschnitt zu dem auf den Grafiken zu den MQTT2-IO-Modulen enthaltenen [[MQTT2-Module_-_Praxisbeispiele#bridgeRegexp|bridgeRegexp]]-Attribut.}}&lt;br /&gt;
&lt;br /&gt;
=== FHEM-externer Broker ===&lt;br /&gt;
==== Beispiel: mosquitto ====&lt;br /&gt;
Eine gern verwendete MQTT-Server-Software ist [http://mosquitto.org Mosquitto]. Sie kann ohne weiteres auf dem Raspberry Pi, der bereits eine FHEM-Installation besitzt, installiert werden und wird keine größere CPU- oder Netzwerklast verursachen. &lt;br /&gt;
&lt;br /&gt;
Eine Anleitung zur Installation findet sich beispielsweise in diesem [http://blog.wenzlaff.de/?p=6487 Blogeintrag]. Im wesentlichen beschränkt sich die Installation eines MQTT Servers aber auf wenige Arbeitsschritte. Bei &#039;&#039;stretch&#039;&#039; ist &#039;&#039;Mosquitto&#039;&#039; bereits in der Distribution enthalten und kann - zusammen mit dem client Befehl &#039;&#039;mosquito_sub&#039;&#039;, der weiter unten benötigt wird, wie folgt installiert und getestet werden&amp;lt;ref&amp;gt;Die für den Betrieb mit FHEM erforderlichen Perl-Module sind teilweise (noch) nicht in den Paketquellen verfügbar. Sie können dennoch statt mit cpan auch als Debian-Paket mit Hilfe von &#039;&#039;dh-make-perl&#039;&#039; installiert werden, wobei vorab das in den Paketquellen bereits vorhandene &#039;&#039;libmodule-pluggable-perl&#039;&#039; installiert werden sollte:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;sudo apt-get install dh-make-perl&amp;lt;br&amp;gt;&lt;br /&gt;
dh-make-perl --install --cpan Net::MQTT::simple&amp;lt;br&amp;gt;&lt;br /&gt;
dh-make-perl --install --cpan Net::MQTT::Constants&amp;lt;br&amp;gt;&lt;br /&gt;
sudo dpkg -i libnet-mqtt-simple-perl*.deb&amp;lt;br&amp;gt;&lt;br /&gt;
sudo dpkg -i libnet-mqtt-perl*.deb&amp;lt;/code&amp;gt;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
{{Randnotiz|RNTyp=g|RNText=Für ältere Distributionen (hier am Beispiel von &#039;&#039;jessie&#039;&#039;) muß ggf. aus einer zusätzlichen Paketquelle installiert werden:&lt;br /&gt;
 wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key&lt;br /&gt;
 sudo apt-key add mosquitto-repo.gpg.key&lt;br /&gt;
 cd /etc/apt/sources.list.d/&lt;br /&gt;
 sudo wget http://repo.mosquitto.org/debian/mosquitto-jessie.list&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
Danach kann die eigentliche Installation durchgeführt werden wie links für &#039;&#039;stretch&#039;&#039; beschrieben.}}&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
  sudo apt-get install mosquitto mosquitto-clients&lt;br /&gt;
 &lt;br /&gt;
 # MQTT Server Test&lt;br /&gt;
 sudo service mosquitto status&lt;br /&gt;
&lt;br /&gt;
 # Start / Stop des Servers&lt;br /&gt;
 sudo service mosquitto stop&lt;br /&gt;
 sudo service mosquitto start&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Danach ist der RPi mit &amp;lt;nowiki&amp;gt;shutdown restart&amp;lt;/nowiki&amp;gt; neu zu starten. &lt;br /&gt;
&lt;br /&gt;
==== IO-Module für externe MQTT-Server ====&lt;br /&gt;
Damit FHEM mit dem MQTT-Server kommuniziert, muss noch ein IO-Device angelegt werden. Dabei stehen zwei Varianten zur Wahl, das Modul [[MQTT (Modul)|MQTT]] oder seit Ende 2018 [[MQTT2_CLIENT]].&lt;br /&gt;
&lt;br /&gt;
Beide Module können auch dazu genutzt werden, um Daten zwischen zwei FHEM-Installationen auszutauschen, insbesondere kann auch 00_MQTT.pm als Client für einen MQTT2_SERVER eingesetzt werden, der &#039;&#039;&#039;auf der anderen Installation&#039;&#039;&#039; als MQTT-Serverdienst eingerichtet ist. Darüber hinaus bestehen eine Vielzahl von Kombinationsmöglichkeiten der diversen IO-Module, wenn die Installation auf mehrere Server verteilt ist.&lt;br /&gt;
Auf einer FHEM-Installation wird jedoch in der Regel nur eines der IO-Module benötigt. &lt;br /&gt;
&lt;br /&gt;
===== MQTT2_CLIENT =====&lt;br /&gt;
Ein MQTT2_CLIENT-IO-Device wird z.B. angelegt mit&lt;br /&gt;
 define myBroker MQTT2_CLIENT 10.0.0.5:1883 ## bitte EIGENE IP-Adresse eintragen&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|Wenn Sie beabsichtigen, MQTT2_CLIENT zu verwenden, sollten Sie zuerst die [[MQTT2-Module - Praxisbeispiele|Praxisbeispiele zu den MQTT2-Modulen]] lesen, und dabei die Hinweise im Artikel [[MQTT2_CLIENT]] beachten.}}&lt;br /&gt;
&lt;br /&gt;
Ein MQTT2_CLIENT-Device kann ebenfals mit Hilfe von [[allowed]] abgesichert werden, um z.B. SSL-verschlüsselte Kommunikation zu ermöglichem. Client-Module zu diesem IO-Typ sind wiederum [[MQTT2_DEVICE]] und {{Link2CmdRef|Anker=MQTT_GENERIC_BRIDGE|Lang=de|Label=MQTT_GENERIC_BRIDGE}}.&lt;br /&gt;
&lt;br /&gt;
===== MQTT (Modul) ===== &lt;br /&gt;
Vorab werden für diese Variante weitere Perl-Pakete benötigt:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # Perl Version ausgeben&lt;br /&gt;
 perl -v&lt;br /&gt;
 # Perl MQTT Module nachinstallieren (läuft ein paar Minuten)&lt;br /&gt;
 sudo cpan install Net::MQTT::Simple&lt;br /&gt;
 sudo cpan install Net::MQTT::Constants&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein IO-Device des Typs MQTT wird z.B. angelegt mit&lt;br /&gt;
{{Randnotiz|RNTyp=g|RNText=Sofern der Broker mit FHEM über localhost kommuniziert, kann als IP 127.0.0.1 verwendet werden.}}&lt;br /&gt;
 define myBroker MQTT 10.0.0.5:1883 ## bitte EIGENE IP-Adresse eintragen&lt;br /&gt;
{{Randnotiz|RNTyp=g|RNText=Außerhalb der offiziellen Quellen sind auch einige ältere Varianten des Moduls MQTT_DEVICE verfügbar, die jeweils spezielle Anforderungen (z.B. für Zigbee2mqtt) separat abbilden. Diese werden hier nicht gesondert behandelt, da solche Sonderfälle heute generischer und einfacher durch den Einsatz von MQTT2_DEVICE abzubilden sind.}}Client-Device-Module zum Modul [[MQTT (Modul)|MQTT]] sind [[MQTT_DEVICE]], {{Link2CmdRef|Anker=MQTT_BRIDGE|Lang=de|Label=MQTT_BRIDGE}} (veraltet) und {{Link2CmdRef|Anker=MQTT_GENERIC_BRIDGE|Lang=de|Label=MQTT_GENERIC_BRIDGE}}. Da &#039;&#039;MQTT_DEVICE&#039;&#039; payload im JSON-Format (im Unterschied zu MQTT2_DEVICE) nicht selbst verarbeiten kann wird hier zusätzlich das Modul {{Link2CmdRef|Anker=expandJSON|Lang=de|Label=expandJSON}} benötigt, um den {{Link2Forum|Topic=66761|LinkText=JSON String auszuwerten}}.&lt;br /&gt;
&lt;br /&gt;
=== Performancefragen... ===&lt;br /&gt;
...oder was sollte man als Lösung wählen, wenn man in die MQTT-Welt einsteigt&amp;lt;ref&amp;gt;vgl. hierzu diesen {{Link2Forum|Topic=94768|Message=875714|LinkText=Beitrag}} von Rudolf König&amp;lt;/ref&amp;gt;?&lt;br /&gt;
Grundsätzlich sollte man davon ausgehen, dass innerhalb von FHEM die Verarbeitung derselben Daten näherungsweise denselben Aufwand bedeuten, unabhängig davon, welche der Implementierungen (&#039;&#039;MQTT2_CLIENT&#039;&#039;, &#039;&#039;MQTT&#039;&#039; oder &#039;&#039;MQTT2_SERVER&#039;&#039;) man konkret wählt.&lt;br /&gt;
Ein externer Broker hat daher vor allem dann Vorteile, wenn die MQTT Daten überwiegend für was anderes (nicht FHEM) verwendet werden, oder MQTT zweckentfremdet wird (wie z.Bsp. für Musikübertragung). Nutzt man das MQTT-Protokoll dagegen vorwiegend innerhalb von FHEM, ist eher der Einsatz von MQTT2_SERVER in Betracht zu ziehen. Dieser soll Anfängern die Anbindung von MQTT Geräten in FHEM einfacher machen. Wer später merkt, dass er doch einen externen Broker benötigt, kann dann immer noch auf MQTT2_CLIENT in Verbindung mit einem anderen Broker wechseln.&lt;br /&gt;
Dagegen ist der Weg von MQTT_DEVICE zu MQTT2_DEVICE mit erheblich mehr Aufwand verbunden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kommunikation zu sonstigen FHEM-Geräten über MQTT  ===&lt;br /&gt;
&lt;br /&gt;
Möchte man Daten von einem [[Gerät]] (im FHEM-Sinn), das &#039;&#039;&#039;nicht&#039;&#039;&#039; vom Typ &#039;&#039;MQTT2_DEVICE&#039;&#039; oder &#039;&#039;MQTT_DEVICE&#039;&#039; (je nach IO-Modul) ist, per MQTT-Protokoll versenden (z.B. für eine andere Visualisierungslösung als FHEMWEB, oder als FHEM2FHEM-Ersatzlösung), oder diese sonstigen Geräte über MQTT-Anweisungen von außen steuern können, hat man mehrere Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
==== MQTT_GENERIC_BRIDGE ====&lt;br /&gt;
===== Allgemeines =====&lt;br /&gt;
Das Modul {{Link2CmdRef|Anker=MQTT_GENERIC_BRIDGE|Lang=en|Label=MQTT_GENERIC_BRIDGE}} ermöglicht es, sein jeweiliges IO-Modul-Gerät zu nutzen, um diesen Kommunikationsweg für beliebig viele andere FHEM-Geräte bereitzustellen. Dabei erfolgt am MQTT_GENERIC_BRIDGE-Gerät selbst nur eine Basiskonfiguration, im Übrigen durch Attribute an dem jeweiligen Gerät selbst. So kann z.B. ein Aktor des Typs [[CUL_HM]] an- oder ausgeschaltet werden oder auch einfach nur seinen aktuellen Schaltzustand per MQTT-Protokoll publizieren.&lt;br /&gt;
 &lt;br /&gt;
Dieses Modul kann seit November 2018 mit allen drei IO-Modul-Varianten zusammen eingesetzt werden, also sowohl mit &#039;&#039;MQTT2_SERVER&#039;&#039; bzw. &#039;&#039;MQTT2_CLIENT&#039;&#039; oder &#039;&#039;MQTT&#039;&#039; (00_MQTT.pm). Für MQTT_GENERIC_BRIDGE wird allerdings auch bei Verwendung der MQTT2-IO&#039;s zusätzliche Software benötigt, insbesondere das Perl-Modul &#039;&#039;libmodule-pluggable-perl&#039;&#039;&amp;lt;ref&amp;gt;Dieses kann über &amp;lt;code&amp;gt;apt-get install libmodule-pluggable-perl&amp;lt;/code&amp;gt; installiert werden&amp;lt;/ref&amp;gt;, damit im Hintergrund auch das Modul [[MQTT (Modul)|MQTT]] geladen werden kann. Damit gelten auch für diesen Modul die Installationsvoraussetzungen für [[MQTT#MQTT_.28Modul.29|MQTT]]!&amp;lt;!--Beta-User: Dieser Satz mit den Installationsvoraussetzungen ist mAn nicht richtig, da die Message-Vararbeitung über die neueren Module anders läuft und daher die betreffenden Module gar nicht benötigt werden. Wäre aber zu verifizieren!--&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===== MQTT_GENERIC_BRIDGE und autocreate bei MQTT2-IO-Modulen =====&lt;br /&gt;
Dabei sollte man jedoch beachten, dass eingehende MQTT-Nachrichten von den MQTT2-IO Modulen (&#039;&#039;MQTT2_SERVER&#039;&#039; oder &#039;&#039;MQTT2_CLIENT&#039;&#039;) nur dann an die &#039;&#039;MQTT_GENERIC_BRIDGE&#039;&#039; zur weiteren Auswertung übergeben werden, wenn entweder&lt;br /&gt;
&lt;br /&gt;
- die &#039;&#039;autocreate&#039;&#039;-Funktion des betreffenden IOs ausgeschaltet wird und bleibt, oder&lt;br /&gt;
&lt;br /&gt;
- eine &#039;&#039;bridgeRegexp&#039;&#039; an einem beliebigen &#039;&#039;MQTT2_DEVICE&#039;&#039; existiert, die die betreffenden Nachrichten mit einer leeren CID zurückgibt.&lt;br /&gt;
&lt;br /&gt;
Die technischen Hintergründe bzgl. autocreate sind diesem {{Link2Forum|Topic=95341|LinkText=Thread}} zu entnehmen. &lt;br /&gt;
&lt;br /&gt;
Beispiel für die Erstellung einer passenden &#039;&#039;bridgeRegexp&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
Es existiert ein &amp;quot;Neben-FHEM&amp;quot; namens &#039;&#039;fhem2&#039;&#039;, das von einem &amp;quot;Haupt-FHEM&amp;quot; namens &#039;&#039;fhem&#039;&#039; aus Nachrichten empfangen soll, die dann an die an &#039;&#039;fhem2&#039;&#039; angeschlossene Hardware weitergegeben werden. Die Nachrichten kommen über ein MQTT2_CLIENT-IO mit der CID &#039;&#039;fhem2&#039;&#039; in &#039;&#039;fhem2&#039;&#039; an. Das Haupt-FHEM sendet mit der &#039;&#039;$base&#039;&#039; &#039;&#039;fhem/&#039;&#039;. Dann wäre in &#039;&#039;fhem2&#039;&#039; folgendes MQTT2_DEVICE anzulegen (der Name kann frei gewählt werden):&lt;br /&gt;
 define M_G_B_bridgeRegex_device MQTT2_DEVICE fhem2&lt;br /&gt;
 attr M_G_B_bridgeRegex_device bridgeRegexp [\b]fhem/.*:.* &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Anwendungsbeispiele =====&lt;br /&gt;
Anwendungsfälle und -beispiele für das Modul sind diesem {{Link2Forum|Topic=91642|LinkText=Thread}} zu entnehmen.&lt;br /&gt;
&lt;br /&gt;
==== MQTT_BRIDGE ====&lt;br /&gt;
Dieses Modul kann nur zusammen mit einem IO-Gerät des Typs [[MQTT (Modul)|MQTT]] verwendet werden. Dabei wird pro weiterzuleitendem anderen FHEM-Gerät eine eigene Instanz dieses Moduls verwendet. Auf den Einsatz dieser Option sollte in neuen Installationen zugunsten von &#039;&#039;MQTT_GENERIC_BRIDGE&#039;&#039; verzichtet werden.&lt;br /&gt;
&lt;br /&gt;
==== Per publish-Befehl am IO-Gerät ====&lt;br /&gt;
Alle drei IO-Module kennen direkte &#039;&#039;publish&#039;&#039;-Anweisungen, mit deren Hilfe beliebige &#039;&#039;payloads&#039;&#039; an beliebige &#039;&#039;topics&#039;&#039; gesendet werden können. Dies kann man z.B. in einem [[notify]] oder [[at]] nutzen, um einzelne Events zu publishen oder Werteanfragen abzusetzen.&lt;br /&gt;
&lt;br /&gt;
Hier eine regelmäßige Werteabfrage auf einen [[EBUS-MQTT2|ebus]]:&lt;br /&gt;
 defmod get_ebus_updates at +*00:15:00 set ebusMQTT publish ebusd/430/Hc1HeatCurve/get;&lt;br /&gt;
 set ebusMQTT publish ebusd/430/HwcTempDesired/get;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== RAW-Events am IO-Gerät (MQTT2.*) ====&lt;br /&gt;
Bei beiden MQTT2-IO-Modulen (MQTT2_SERVER und MQTT2_CLIENT) kann per [[Regulärer Ausdruck|regulärem Ausdruck]] festgelegt werden, welche Nachrichten ein Event erzeugen sollen, auf das dann wieder z.B. mit einem [[notify]] reagiert werden kann, z.B. um beliebige Schaltaktionen auszulösen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== MQTT-Clients (Beispiele) ==&lt;br /&gt;
&lt;br /&gt;
===Arduino-library===&lt;br /&gt;
Zur Kommunikation mit dem Broker von Seiten eines [[Arduino|Arduinos]] mit selbst erstellten Sketches böte sich der PubSubClient an.&lt;br /&gt;
&lt;br /&gt;
===PC-Software===&lt;br /&gt;
Um die Funktionalität des Brokers zu testen kann z.B. ein Analyse-Tool wie MQTT.fx verwendet werden, oder die im Paket &#039;&#039;mosquitto-clients&#039;&#039; enthaltenen Linux-Kommandozeilen-Programme &#039;&#039;mosquitto_sub&#039;&#039; und &#039;&#039;mosquitto_pub&#039;&#039;. Letzterer könnte z.E. auch aus beliebigen &#039;&#039;shell-scripten&#039;&#039; heraus aufgerufen werden. Als Perl-Bibliothek steht alternativ z.B. [https://metacpan.org/pod/distribution/AnyEvent-MQTT/bin/anyevent-mqtt-pub anyevent-mqtt-pub] zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
=== Tasmota ===&lt;br /&gt;
Eine derzeit oft genutzte Möglichkeit für MQTT bilden die [[Sonoff]]-Geräte und weitere [[ESP8266]]-basierte Hardware, die unter vielen Handelsnamen erhältlich sind. Werden diese mit Tasmota (&#039;&#039;&#039;T&#039;&#039;&#039;heo &#039;&#039;&#039;A&#039;&#039;&#039;rends &#039;&#039;&#039;S&#039;&#039;&#039;onoff &#039;&#039;&#039;M&#039;&#039;&#039;QTT &#039;&#039;&#039;O&#039;&#039;&#039;ver &#039;&#039;&#039;T&#039;&#039;&#039;he &#039;&#039;&#039;A&#039;&#039;&#039;ir - einer offenen Firmware von [https://github.com/arendst arendst]) geflasht, so kommunizieren sie über MQTT. Um diese Geräte einzubinden, ist wie folgt vorzugehen. Zuerst ist ein Serverdienst (Broker) bereitzustellen, wie oben beschrieben.&lt;br /&gt;
&lt;br /&gt;
Unter Sonoff sind einige Topics voreingestellt. arendst stellt insbesondere drei Topic-Präfixe bereit, die seiner Meinung jedes Topic einleiten sollen (in den Eingabemasken als &amp;quot;%prefix%&amp;quot; notiert). Das sind einmal Kommandos (abgekürzt als cmnd), die dazu dienen, Befehle auszuführen. Daten werden mit tele und stat übertragen. Ein Topic besteht dann zuerst aus diesem Präfix und danach dem eigentlichen Topic. Wer also beispielsweise einem Sonoff_Switch einen Befehl senden will, sollte als Topic cmnd/Sonoff_Switch wählen. Wenn der Switch ein- und ausgeschaltet werden kann, muss der Topic noch das Wort POWER enthalten (in MQTT werden viele Kennworte komplett groß geschrieben). Der Topic lautet damit vollständig &amp;quot;cmnd/Sonoff_Switch/POWER/set&amp;quot; &lt;br /&gt;
&lt;br /&gt;
{{Randnotiz|RNTyp=g|RNText=Dabei ist darauf zu achten, dass für den Parameter &#039;&#039;topic = %topic% (sonoff)&#039;&#039; statt &#039;&#039;sonoff&#039;&#039; ein gerätespezifischer eigener Name eingetragen wird. Hierzu kann man z.B. auch die dynamisch aus der Chip-ID erzeugte Kennung &#039;&#039;DVES_%06X&#039;&#039; verwenden, indem man die unter &#039;&#039;client (DVES_8BABA9)&#039;&#039; zu findende Angabe kopiert. Die eigentliche Umbenennung zu einem &amp;quot;sprechenden Namen&amp;quot; kann dann innerhalb von FHEM - mittels &#039;&#039;rename&#039;&#039; oder ggf. mit einem &#039;&#039;alias&#039;&#039; - erfolgen.}}&lt;br /&gt;
&lt;br /&gt;
Link zum Forum: {{Link2Forum|Topic=27532|LinkText=MQTT FHEM Einrichtung}} (hier als &#039;&#039;MQTT_DEVICE&#039;&#039;!):&lt;br /&gt;
&lt;br /&gt;
 ### FHEM Device mit MQTT verbinden ###&lt;br /&gt;
 define Sonoff_Switch MQTT_DEVICE&lt;br /&gt;
 attr Sonoff_Switch IODev myBroker&lt;br /&gt;
 attr Sonoff_Switch devStateIcon ON:rc_GREEN:OFF OFF:rc_RED:ON&lt;br /&gt;
 attr Sonoff_Switch icon hue_filled_br30&lt;br /&gt;
 attr Sonoff_Switch publishSet ON OFF cmnd/TestSwitch/POWER&lt;br /&gt;
 attr Sonoff_Switch room MQTT&lt;br /&gt;
 attr Sonoff_Switch subscribeReading_Licht stat/Sonoff_Switch/POWER&lt;br /&gt;
 attr Sonoff_Switch subscribeReading_Sensor tele/Sonoff_Switch/SENSOR&lt;br /&gt;
 attr Sonoff_Switch subscribeReading_Status stat/Sonoff_Switch/STATUS&lt;br /&gt;
 attr Sonoff_Switch webCmd ON:OFF&lt;br /&gt;
&lt;br /&gt;
Der hier dargestellte Beispielcode realisiert die Kommunikation zwischen FHEM und dem sonoff Modul via MQTT Broker. Zu beachten ist hier, dass &#039;&#039;&#039;subscribeReading_Licht&#039;&#039;&#039; und &#039;&#039;&#039;subscribeReading_Status&#039;&#039;&#039; unterschiedliche Syntax des Topic Strings haben!&lt;br /&gt;
&lt;br /&gt;
=== OpenMQTTGateway ===&lt;br /&gt;
Um verschiedene Systeme wie BLE usw. auf MQTT zu bringen bietet sich OpenMQTTGateway an.&lt;br /&gt;
&lt;br /&gt;
Ich habe es für BLE kompiliert und auf einem ESP32 installiert. Hierzu braucht man nur das blanke Board ohne Zusatzhardware.&lt;br /&gt;
&lt;br /&gt;
Weiter infos hier: [https://github.com/1technophile/OpenMQTTGateway]&lt;br /&gt;
&lt;br /&gt;
In FHEM wird das ganze über den eigenen Broker oder einen extern Broker (z.B.: Mosquitto) eingebunden.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich legt ihr noch ein Device hierzu an.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;define MQTT2_OMG1 MQTT2_DEVICE&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ich habe es noch in den Raum MQTT2 geschoben.&lt;br /&gt;
&lt;br /&gt;
Mit &amp;lt;code&amp;gt;set MQTT2_OMG1 attrTemplate OpenMQTTGateway_MCU&amp;lt;/code&amp;gt; wird das Template festgelegt.&lt;br /&gt;
&lt;br /&gt;
Aus diesem Device raus könnt ihr euch nun auch ein Dummy für z.B. einen MiFlora anlegen lassen. Das geschieht dann über &amp;lt;code&amp;gt;set MQTT2_OMG1 attrTemplate OpenMQTTGateway_BT_mi_flora_sensor&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sicherheit ==&lt;br /&gt;
Prinzipiell ist MQTT ebenso sicher wie eine Postkarte. Solange man es nicht extra absichert, kann jeder der, im eigenen LAN ist (und die Adresse vom Broker kennt) alle Topics mitlesen.&lt;br /&gt;
:&amp;lt;code&amp;gt;meinHaus/Flur/Haustuer:open / close&amp;lt;/code&amp;gt;&lt;br /&gt;
bietet unter diesen Umständen reichlich Raum für Verbesserungen! &lt;br /&gt;
&lt;br /&gt;
Abhilfe:&lt;br /&gt;
=== Username / Passwort ===&lt;br /&gt;
Zunächst kann man erst mal einen Username / Passwort vergeben, was alle IO-Device-Module unterstützen. Da ist zwar auch noch lange nicht sicher, aber zumindest steigert es den Aufwand schon mal. Jetzt muss man zumindest schon mal Pakete sniffen und verstehen, um unbefugt zu lesen oder gar zu publishen.&lt;br /&gt;
&lt;br /&gt;
=== TLS ===&lt;br /&gt;
Um wirklich sicher zu werden, führt kein Weg an TLS vorbei. &lt;br /&gt;
&lt;br /&gt;
Der MQTT-Client in [[#Tasmota|Tasmota]] (für ESP8266) kann mit TLS betrieben werden, vgl. [https://github.com/arendst/Tasmota/wiki/TLS Beschreibung im Tasmota-Wiki].&lt;br /&gt;
&lt;br /&gt;
Leider kann z.B. ein Arduino das schlicht nicht mehr, da die einfacheren Modelle nicht über ausreichend Speicher und die Rechenleistung verfügen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;(Hier fehlt eine Anleitung für allowed usw.)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Probleme ==&lt;br /&gt;
=== Anweisung und Ergebnis weichen voneinander ab ===&lt;br /&gt;
In der Regel melden MQTT-fähige Geräte entweder den Erhalt einer Nachricht zurück oder den Status nach Durchführung der in der &#039;&#039;payload&#039;&#039; enthaltenen Anweisung. Dabei findet aber in der Regel beim Empfänger eine Verarbeitung der Nachricht statt, ggf. wird diese auch weitergesendet und nochmals verarbeitet, bevor dann ggf. eine Rückmeldung des neuen Status an den MQTT-Server erfolgt. Handelt es sich um einfache on/off-Befehle, bleibt Anweisung und Ergebnis in der Regel identisch. Bei anderen, namentlich bei Dimmer-Werten, kann es zu Rundungsdifferenzen bei nummerischen Werten kommen. So kann z.B. ein Dimm-Wert von 70% gesetzt werden, zürückgemeldet wird dann aber 72% (oder 67%). &lt;br /&gt;
Dies ist technisch bedingt, vermeiden kann das jedoch in aller Regel nur der Autor der jeweiligen software/firmware auf dem &amp;quot;rechnenden&amp;quot; Gerät.&lt;br /&gt;
&lt;br /&gt;
=== Unbeabsichtigte Schleifen ===&lt;br /&gt;
Durch Fehler in der topic-Struktur können unbeabsichtigte Schleifen entstehen, die FHEM komplett blockieren können. Es ist unbedingt darauf zu achten, dass die jeweiligen Sende- und Empfangs-topics andere sind!&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
=== Welche Infos sollten Anfragen im MQTT-Forum enthalten? ===&lt;br /&gt;
* Anfragen bitte nur zur aktuellsten FHEM-Version: Befehl &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; ergibt Ausgabe &amp;quot;nothing to do...&amp;quot;&lt;br /&gt;
* detaillierte Beschreibung des Problems&lt;br /&gt;
* Art der Einbindung&lt;br /&gt;
** eingesetzter MQTT-Server? (=&amp;gt; MQTT2_SERVER oder externer Serverdienst wie mosquitto?)&lt;br /&gt;
** Wenn externer Server: Interface-Modul: MQTT2_CLIENT oder 00_MQTT.pm?&lt;br /&gt;
** Bitte einen Hinweis, falls MQTT_GENERIC_BRIDGE definiert ist bzw. auch ein list von der MQTT_GENERIC_BRIDGE.&lt;br /&gt;
** TYPE des eigentlichen MQTT-Devices (MQTT2_DEVICE, MQTT_DEVICE, TASMOTA_DEVICE, ...) &lt;br /&gt;
* Informationen zur eigentlichen Komponente:&lt;br /&gt;
** Hersteller, ggf. aktuell verwendete firmware incl. Version (Beispiel: ein Shelly-Gerät mit originaler firmware verhält sich anders als dasselbe Gerät mit Tasmota-, ESPEasy oder ESPurna-firmware!).&lt;br /&gt;
** Bei weniger gängigen Komponenten oder Diensten:&lt;br /&gt;
*** (sofern vorhanden): Link zu Projektseiten, MQTT-API-Seiten usw..&lt;br /&gt;
*** Mittschnitte des MQTT-Verkehrs (z.B. durch Einschalten der rawEvents an den MQTT2-Interface-Modulen, s.o.).&lt;br /&gt;
** Ein &#039;&#039;list&#039;&#039; des eigentlichen Devices - bei MQTT2_DEVICE gerne in Form einer RAW-Definition (&#039;&#039;list -r &amp;lt;devicename&amp;gt;&#039;&#039;).&lt;br /&gt;
* Bei MQTT2-Einbindung und aktiviertem &#039;&#039;autocreate&#039;&#039; an den Interface-Modulen den Status des &#039;&#039;autocreate&#039;&#039;-&#039;Devices: &lt;br /&gt;
 list TYPE=autocreate&lt;br /&gt;
=== Älterer FAQ-Thread im Forum ===&lt;br /&gt;
Dieser ist {{Link2Forum|Topic=70119|LinkText=hier}} zu finden. Bitte beachten: es sind einige grundlegende Informationen und Links zu vielen Tools und Fundstellen enthalten, allerdings nur bis zum Stand des Jahres 2017. Die neue Modulgeneration MQTT2_.* wird dort nicht behandelt.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [http://mqtt.org Offizielle Homepage von MQTT, englisch]&lt;br /&gt;
* [http://www.hivemq.com/blog/mqtt-essentials-part-1-introducing-mqtt Sehr gute Einführung, englisch, sind 5 lesenswerte Teile]&lt;br /&gt;
* [https://www.heise.de/developer/artikel/MQTT-Protokoll-fuer-das-Internet-der-Dinge-2168152.html Ein Exkurs von Heise mit Beispielen, deutsch, sehr lesenswert]&lt;br /&gt;
* [http://www.mqttfx.org/ MQTT FX - ein sehr praktisches Analysetool]&lt;br /&gt;
* {{Link2Forum|Topic=69230|LinkText=Diskussionsthread im Forum}}&lt;br /&gt;
* {{Link2Forum|Topic=92888|LinkText=Thread, zur Entstehungsgeschichte von MQTT2_CLIENT}}&lt;br /&gt;
* {{Link2Forum|Topic=93255|LinkText=Ankündigungsthread zur MQTT2-Erweiterung der MQTT_GENERIC_BRIDGE}}&lt;br /&gt;
* [[MQTT_Einf%C3%BChrung_Teil_2|Teil 2 der MQTT Einführung]]: Detailaspekte (vorrangig zur Modulfamilie MQTT/MQTT_DEVICE)&lt;br /&gt;
* [[MQTT Einführung Teil 3|Teil 3 der MQTT Einführung]]: Arduino-Client selbst programmieren&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Glossary]]&lt;br /&gt;
[[Kategorie:HOWTOS]]&lt;br /&gt;
[[Kategorie:MQTT|Einführung]]&lt;br /&gt;
[[Kategorie:MQTT| ]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=33383</id>
		<title>CPAN</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=33383"/>
		<updated>2020-06-13T18:23:59Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Typo fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= CPAN =&lt;br /&gt;
&lt;br /&gt;
Das CPAN, Comprehensive Perl Archive Network, ist ein weltweit verteiltes Netzwerk für Perl-Module, das seit 1995 besteht und aktuell etwa 200 000 Module umfasst.&lt;br /&gt;
&lt;br /&gt;
Siehe auch hier eine [https://www.cpan.org/modules/INSTALL.html Zusammenfassung des CPAN-Projektes].&lt;br /&gt;
&lt;br /&gt;
== Clients ==&lt;br /&gt;
&lt;br /&gt;
=== Plattformunabhängig ===&lt;br /&gt;
&lt;br /&gt;
Das CPAN bietet drei plattformunabhängige Clients an, von denen zwei hier beschrieben werden. Die &#039;&#039;Empfehlung&#039;&#039; ist, &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; zu nutzen.&lt;br /&gt;
&lt;br /&gt;
==== cpanminus ====&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/distribution/App-cpanminus/bin/cpanm cpanminus] (&amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt;) ist der bevorzugte Weg, wie CPAN-Pakete installiert werden sollten. cpan-minus ist, wie &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; ein CPAN-Paket, das aber auch für viele Betriebssystem als fertiges Paket portiert wurde.&lt;br /&gt;
&lt;br /&gt;
cpan-minus bietet einen [http://cpanmin.us/ Quickstart] an, der auf jedem System läuft, auf dem Perl installiert ist. Dazu muss folgender Befehl auf der Kommandozeile ausgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;curl -L https://cpanmin.us | perl - App::cpanminus&amp;lt;/pre&amp;gt;&lt;br /&gt;
Aus Sicherheitsgründen sollte vor Ausführung des Befehls überprüft werden, was unter [http://cpanmin.us/ cpanmin.us] zu finden ist, da ggf. Schadcode unbemerkt eingeschmuggelt werden könnte.&lt;br /&gt;
&lt;br /&gt;
Ist der Client &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; installiert, kann mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpanm Paket::Name&amp;lt;/pre&amp;gt;&lt;br /&gt;
ein Paket (in diesem Falle das nicht-existende Paket &amp;lt;code&amp;gt;Paket::Name&amp;lt;/code&amp;gt;) installiert werden. Die Option &amp;lt;code&amp;gt;--sudo&amp;lt;/code&amp;gt; sorgt dafür, dass cpanminus die Installation als Superuser versucht (ggf. muss ein Passwort eingegeben werden).&lt;br /&gt;
&lt;br /&gt;
==== Exkurs: cpan-outdated ====&lt;br /&gt;
&lt;br /&gt;
Das Paket [https://metacpan.org/pod/distribution/cpan-outdated/script/cpan-outdated &amp;lt;code&amp;gt;cpan-outdated&amp;lt;/code&amp;gt;] erzeugt eine cpanminus-kompatible Liste an CPAN-Paketen, die aktualisiert werden können, z.B.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ cpan-outdated &lt;br /&gt;
A/AN/ANDK/CPAN-2.27.tar.gz&lt;br /&gt;
L/LE/LEONT/Test-Harness-3.42.tar.gz&lt;br /&gt;
B/BI/BINGOS/Archive-Tar-2.36.tar.gz&lt;br /&gt;
T/TO/TODDR/autodie-2.32.tar.gz&lt;br /&gt;
R/RU/RURBAN/B-Debug-1.26.tar.gz&lt;br /&gt;
I/IL/ILMARI/bareword-filehandles-0.007.tar.gz&lt;br /&gt;
P/PJ/PJACKLAM/bignum-0.51.tar.gz&lt;br /&gt;
X/XS/XSAWYERX/Carp-1.50.tar.gz&lt;br /&gt;
L/LE/LEEJO/CGI-4.47.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Clone-0.45.tar.gz&lt;br /&gt;
M/ML/MLEHMANN/common-sense-3.75.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Bzip2-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Zlib-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/IO-Compress-2.093.tar.gz&lt;br /&gt;
H/HM/HMBRAND/Config-Perl-V-0.31.tgz&lt;br /&gt;
A/AT/ATOOMIC/TimeDate-2.33.tar.gz&lt;br /&gt;
P/PM/PMQS/DB_File-1.853.tar.gz&lt;br /&gt;
H/HU/HURRICUP/Devel-Camelcadedb-v2019.1.tar.gz&lt;br /&gt;
P/PJ/PJCJ/Devel-Cover-1.36.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Devel-PPPort-3.58.tar.gz&lt;br /&gt;
M/MS/MSHELOR/Digest-SHA-6.02.tar.gz&lt;br /&gt;
R/RJ/RJBS/Email-Sender-1.300034.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Sehr nützlich ist die Kombination aus cpanminus und cpan-outdated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan-outdated | cpanm --sudo&amp;lt;/pre&amp;gt;&lt;br /&gt;
Diese Befehlssequenz aktualisiert alle aktualisierbaren CPAN-Pakete mit Hilfe von cpanminus (als Superuser).&lt;br /&gt;
&lt;br /&gt;
==== cpan ====&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/CPAN &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;] ist der mit jeder Perl-Installation mitgelieferte Client für das CPAN und lässt sich entweder mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;perl -MCPAN -e shell&amp;lt;/pre&amp;gt;&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan&amp;lt;/pre&amp;gt;&lt;br /&gt;
starten. Es wird ein interaktiver Client gestartet; mit &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; kann eine sehr umfangreiche Hilfe aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Ein Modul lässt sich am einfachsten mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan install PAKET::NAME&amp;lt;/pre&amp;gt;&lt;br /&gt;
installieren (hier das nicht-existente Paket &amp;lt;code&amp;gt;PAKET::NAME&amp;lt;/code&amp;gt;). &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; eignet sich weniger gut um Module zu installieren oder zu aktualisieren, aber sehr gut um nach Paketen zu suchen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;i /JSON/&amp;lt;/pre&amp;gt;&lt;br /&gt;
findet jedes Paket, das die Zeichenkette &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; im Bereich Autor, Bundle, Distribution oder Modul enthält. Das sind meist viele Ergebnisse, aber liefert einen Überblick &amp;amp;quot;was geht&amp;amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß ist &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; recht störrisch in der Handhabung. Deshalb empfehle ich die Nutzung von cpanminus.&lt;br /&gt;
&lt;br /&gt;
=== OS-Paketmanager ===&lt;br /&gt;
&lt;br /&gt;
==== Debian und Derivate (Ubuntu, Raspbian, etc.) ====&lt;br /&gt;
&lt;br /&gt;
Vom Debian-Projekt werden viele, aber lange nicht alle, Pakete des CPAN auch als Pakete für den eingebauten Paketmanager &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt; [https://packages.debian.org/stable/perl/ bereitsgestellt]. Dort sind momentan etwa 4 000 Pakete verfügbar, d.h. rund 2% der im CPAN verfügbaren Pakete. Es ist nicht immer trivial, ein Paket zu finden. Ein einfacher Fall ist z.B. das Paket &amp;lt;code&amp;gt;Readonly&amp;lt;/code&amp;gt;, der über &amp;lt;code&amp;gt;cpanm Readonly&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;apt-get install libreadonly-perl&amp;lt;/code&amp;gt; installiert werden könnte. Im Allgemeinen kann man sagen, dass sich der Name des &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;-Paketes aus dem Prefix &amp;lt;code&amp;gt;lib&amp;lt;/code&amp;gt;, gefolgt vom Paketnamen in Kleinbuchstaben, bei dem die &amp;lt;code&amp;gt;::&amp;lt;/code&amp;gt; durch &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt; ersetzt wurden, und dem Suffix &amp;lt;code&amp;gt;-perl&amp;lt;/code&amp;gt; zusammensetzt:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! CPAN&lt;br /&gt;
! Debian-Paket&lt;br /&gt;
|-&lt;br /&gt;
| Rose::URI&lt;br /&gt;
| librose-uri-perl&lt;br /&gt;
|-&lt;br /&gt;
| Sah::Schemas::Rinci&lt;br /&gt;
| libsah-schemas-rinci-perl&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Kein Beispiel wäre vollständig ohne Ausnahme, z.B.:&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;libromana-perligata-perl&amp;lt;/code&amp;gt;] installiert das Perl-Paket [https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;Lingua::Romana::Perligata&amp;lt;/code&amp;gt;], müsste nach der selbstgewählten Konvention aber &amp;lt;code&amp;gt;liblingua-romana-perligata-perl&amp;lt;/code&amp;gt; heißen.&lt;br /&gt;
&lt;br /&gt;
Vorteilhaft ist, dass man die Pakete zusammen mit anderen Debian-Paketen automatisch auf dem aktuellen Stand halten kann, z.B. [https://wiki.debian.org/UnattendedUpgrades &amp;lt;code&amp;gt;unattended-upgrades&amp;lt;/code&amp;gt;] - man spart so eine doppelte Implementierung der Updates.&lt;br /&gt;
&lt;br /&gt;
Wiederum von Nachteil ist, dass man mit einer auf ein Release festgelegten Quelle irgendwann auch keine Updates der Perl-Pakete mehr erhält.&lt;br /&gt;
&lt;br /&gt;
==== SuSE Linux ====&lt;br /&gt;
&lt;br /&gt;
YaST bietet aktuell etwa 3 121 der rund 200 000 Pakete in [https://build.opensuse.org/project/show/devel:languages:perl &amp;lt;code&amp;gt;devel:languages:perl&amp;lt;/code&amp;gt;] an, dazu kommen noch einige Community-Pakete mit einer trivial nicht feststellbaren Anzahl an Paketen. Im Paket [https://build.opensuse.org/package/show/devel:languages:perl:CPAN-A/perl-App-cpanminus &amp;lt;code&amp;gt;perl-App-cpanminus&amp;lt;/code&amp;gt;] ist &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; enthalten.&lt;br /&gt;
&lt;br /&gt;
==== RedHat Linux ====&lt;br /&gt;
&lt;br /&gt;
==== MacOS ====&lt;br /&gt;
&lt;br /&gt;
Für MacOS gilt, dass das installierte Perl den &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;-Client und eine Auswahl an Module mitbringt. &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; lässt sich installieren und sollte auch der Weg der Wahl sein. Es ist außerdem möglich, Pakete über [https://www.macports.org/ MacPorts] zu installieren. MacPorts bietet noch weniger Pakete (aktuell 1 797 für Perl 5.26, 1 799 für Perl 5.28) als Debian.&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
&lt;br /&gt;
[https://www.activestate.com/products/perl/downloads/ ActiveState] bietet eine Perl-Distribution an, die bereits mit einigen Module, 214 bei [https://platform.activestate.com/ActiveState/ActivePerl-5.28 Perl 5.28], ausgeliefert wird.&lt;br /&gt;
&lt;br /&gt;
== Empfohlene Pakete ==&lt;br /&gt;
&lt;br /&gt;
Im FHEM-Umfeld werden aktuell rund 120 CPAN-Pakete (mit Sub-Paketen) eingesetzt die keine [https://www.perl.com/article/what-is-the-perl-core-/ Core-Module] sind und ggf. für ein FHEM-Modul [[Meta|nachinstalliert]] werden müssen:&lt;br /&gt;
&lt;br /&gt;
* Authen::OATH&lt;br /&gt;
* AutoLoader&lt;br /&gt;
* B&lt;br /&gt;
* Carp&lt;br /&gt;
* Color&lt;br /&gt;
* Compress::Zlib&lt;br /&gt;
* Convert::Base32&lt;br /&gt;
* Cpanel::JSON::XS&lt;br /&gt;
* Crypt::Argon2&lt;br /&gt;
* Crypt::CBC&lt;br /&gt;
* Crypt::Cipher::AES&lt;br /&gt;
* Crypt::ECB&lt;br /&gt;
* Crypt::Mode::CBC&lt;br /&gt;
* Crypt::MySQL&lt;br /&gt;
* Crypt::NaCl::Sodium&lt;br /&gt;
* Crypt::Rijndael&lt;br /&gt;
* Crypt::Rijndael_PP&lt;br /&gt;
* Crypt::URandom&lt;br /&gt;
* DBI&lt;br /&gt;
* DBI::Const::GetInfoType&lt;br /&gt;
* Data::Dumper&lt;br /&gt;
* Data::UUID&lt;br /&gt;
* Date::Parse&lt;br /&gt;
* DateTime&lt;br /&gt;
* Device::Firmata&lt;br /&gt;
* Device::Firmata::Base&lt;br /&gt;
* Device::Firmata::Constants&lt;br /&gt;
* Device::Firmata::Error&lt;br /&gt;
* Device::Firmata::Language&lt;br /&gt;
* Device::Firmata::Platform&lt;br /&gt;
* Device::Firmata::Protocol&lt;br /&gt;
* Device::SerialPort&lt;br /&gt;
* Device::USB&lt;br /&gt;
* Digest::CRC&lt;br /&gt;
* Digest::SHA1&lt;br /&gt;
* Encode::Detect::Detector&lt;br /&gt;
* Expect&lt;br /&gt;
* File::HomeDir&lt;br /&gt;
* HTML::Entities&lt;br /&gt;
* HTML::Parser&lt;br /&gt;
* HTTP::Cookies&lt;br /&gt;
* HTTP::Daemon&lt;br /&gt;
* HTTP::Headers&lt;br /&gt;
* HTTP::Request&lt;br /&gt;
* HTTP::Request::Common&lt;br /&gt;
* IO::Interface::Simple&lt;br /&gt;
* IO::Socket::Multicast&lt;br /&gt;
* IO::Socket::Multicast6&lt;br /&gt;
* IO::Socket::SSL&lt;br /&gt;
* IO::Socket::Timeout&lt;br /&gt;
* IO::String&lt;br /&gt;
* Image::ExifTool&lt;br /&gt;
* Image::LibRSVG&lt;br /&gt;
* Image::Size&lt;br /&gt;
* Inline&lt;br /&gt;
* JSON&lt;br /&gt;
* JSON::MaybeXS&lt;br /&gt;
* JSON::XS&lt;br /&gt;
* JSON::backportPP&lt;br /&gt;
* JsonMod::JSON::Path::Node&lt;br /&gt;
* LWP&lt;br /&gt;
* LWP::Simple&lt;br /&gt;
* LWP::UserAgent~6&lt;br /&gt;
* Linux::Inotify2&lt;br /&gt;
* LiquidCrystal&lt;br /&gt;
* Lirc::Client&lt;br /&gt;
* List::MoreUtils&lt;br /&gt;
* MIME::Lite&lt;br /&gt;
* MP3::Info&lt;br /&gt;
* MP3::Tag&lt;br /&gt;
* MP3::Tag::CDDB_File&lt;br /&gt;
* MP3::Tag::Cue&lt;br /&gt;
* MP3::Tag::File&lt;br /&gt;
* MP3::Tag::ID3v1&lt;br /&gt;
* MP3::Tag::ID3v2&lt;br /&gt;
* MP3::Tag::ImageExifTool&lt;br /&gt;
* MP3::Tag::ImageSize&lt;br /&gt;
* MP3::Tag::Inf&lt;br /&gt;
* MP3::Tag::LastResort&lt;br /&gt;
* MP3::Tag::ParseData&lt;br /&gt;
* Mail::IMAPClient&lt;br /&gt;
* Mojolicious~5.54&lt;br /&gt;
* Net::Address::IP::Local&lt;br /&gt;
* Net::Bonjour&lt;br /&gt;
* Net::FTPSSL&lt;br /&gt;
* Net::Jabber&lt;br /&gt;
* Net::MQTT::Constants&lt;br /&gt;
* Net::MQTT::Message&lt;br /&gt;
* Net::MQTT::Message::JustMessageId&lt;br /&gt;
* Net::Rendezvous&lt;br /&gt;
* Net::SIP&lt;br /&gt;
* Net::SIP::Packet&lt;br /&gt;
* Net::SMTP::SSL&lt;br /&gt;
* Net::Telnet&lt;br /&gt;
* Net::UPnP::AV::MediaRenderer&lt;br /&gt;
* Net::UPnP::AV::MediaServer&lt;br /&gt;
* Net::UPnP::ControlPoint&lt;br /&gt;
* Net::UPnP::Device&lt;br /&gt;
* Net::UPnP::Service&lt;br /&gt;
* Net::XMPP::Namespaces&lt;br /&gt;
* Nmap::Parser&lt;br /&gt;
* Path::Tiny&lt;br /&gt;
* Paws::Polly&lt;br /&gt;
* Perl::PrereqScanner::NotQuiteLite&lt;br /&gt;
* RPC::XML::Client&lt;br /&gt;
* RPC::XML::Server&lt;br /&gt;
* RiveScript&lt;br /&gt;
* SOAP::Lite&lt;br /&gt;
* Text::Iconv&lt;br /&gt;
* Try::Tiny&lt;br /&gt;
* UPnP::Common&lt;br /&gt;
* UPnP::ControlPoint&lt;br /&gt;
* URI::Escape&lt;br /&gt;
* WWW::Jawbone::Up&lt;br /&gt;
* Win32::SerialPort&lt;br /&gt;
* XML::LibXML&lt;br /&gt;
* XML::Parser::Lite&lt;br /&gt;
&lt;br /&gt;
[https://raw.githubusercontent.com/fhem/doc-wiki/master/DE/Howtos/fhem-cpan-modules.txt Liste als plain text], z.B. um sie bei einer automatisierten Installation verwenden zu können. Die Liste wurde mit &amp;lt;code&amp;gt;Perl::PrereqScanner&amp;lt;/code&amp;gt; aus dem &amp;lt;code&amp;gt;FHEM/&amp;lt;/code&amp;gt;-Verzeichnis erstellt, durch &amp;lt;code&amp;gt;Core::List&amp;lt;/code&amp;gt; gefiltert und mit &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; auf Nicht-CPAN-Module (z.B. &amp;lt;code&amp;gt;FHEM::Meta&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;DevIO&amp;lt;/code&amp;gt;) geprüft.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HOWTOS]] &lt;br /&gt;
[[Kategorie:Systemadministration]] &lt;br /&gt;
[[Kategorie:Perl]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=33382</id>
		<title>CPAN</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=33382"/>
		<updated>2020-06-13T18:21:59Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= CPAN =&lt;br /&gt;
&lt;br /&gt;
Das CPAN, Comprehensive Perl Archive Network, ist ein weltweit verteiltes Netzwerk für Perl-Module, das seit 1995 besteht und aktuell etwa 200 000 Module umfasst.&lt;br /&gt;
&lt;br /&gt;
Siehe auch hier eine [https://www.cpan.org/modules/INSTALL.html Zusammenfassung des CPAN-Projektes].&lt;br /&gt;
&lt;br /&gt;
== Clients ==&lt;br /&gt;
&lt;br /&gt;
=== Plattformunabhängig ===&lt;br /&gt;
&lt;br /&gt;
Das CPAN bietet drei plattformunabhängige Clients an, von denen zwei hier beschrieben werden. Die &#039;&#039;Empfehlung&#039;&#039; ist, &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; zu nutzen.&lt;br /&gt;
&lt;br /&gt;
==== cpanminus ====&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/distribution/App-cpanminus/bin/cpanm cpanminus] (&amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt;) ist der bevorzugte Weg, wie CPAN-Pakete installiert werden sollten. cpan-minus ist, wie &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; ein CPAN-Paket, das aber auch für viele Betriebssystem als fertiges Paket portiert wurde.&lt;br /&gt;
&lt;br /&gt;
cpan-minus bietet einen [http://cpanmin.us/ Quickstart] an, der auf jedem System läuft, auf dem Perl installiert ist. Dazu muss folgender Befehl auf der Kommandozeile ausgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;curl -L https://cpanmin.us | perl - App::cpanminus&amp;lt;/pre&amp;gt;&lt;br /&gt;
Aus Sicherheitsgründen sollte vor Ausführung des Befehls überprüft werden, was unter [http://cpanmin.us/ cpanmin.us] zu finden ist, da ggf. Schadcode unbemerkt eingeschmuggelt werden könnte.&lt;br /&gt;
&lt;br /&gt;
Ist der Client &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; installiert, kann mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpanm Paket::Name&amp;lt;/pre&amp;gt;&lt;br /&gt;
ein Paket (in diesem Falle das nicht-existende Paket &amp;lt;code&amp;gt;Paket::Name&amp;lt;/code&amp;gt;) installiert werden. Die Option &amp;lt;code&amp;gt;--sudo&amp;lt;/code&amp;gt; sorgt dafür, dass cpanminus die Installation als Superuser versucht (ggf. muss ein Passwort eingegeben werden).&lt;br /&gt;
&lt;br /&gt;
==== Exkurs: cpan-outdated ====&lt;br /&gt;
&lt;br /&gt;
Das Paket [https://metacpan.org/pod/distribution/cpan-outdated/script/cpan-outdated &amp;lt;code&amp;gt;cpan-outdated&amp;lt;/code&amp;gt;] erzeugt eine cpanminus-kompatible Liste an CPAN-Paketen, die aktualisiert werden können, z.B.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ cpan-outdated &lt;br /&gt;
A/AN/ANDK/CPAN-2.27.tar.gz&lt;br /&gt;
L/LE/LEONT/Test-Harness-3.42.tar.gz&lt;br /&gt;
B/BI/BINGOS/Archive-Tar-2.36.tar.gz&lt;br /&gt;
T/TO/TODDR/autodie-2.32.tar.gz&lt;br /&gt;
R/RU/RURBAN/B-Debug-1.26.tar.gz&lt;br /&gt;
I/IL/ILMARI/bareword-filehandles-0.007.tar.gz&lt;br /&gt;
P/PJ/PJACKLAM/bignum-0.51.tar.gz&lt;br /&gt;
X/XS/XSAWYERX/Carp-1.50.tar.gz&lt;br /&gt;
L/LE/LEEJO/CGI-4.47.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Clone-0.45.tar.gz&lt;br /&gt;
M/ML/MLEHMANN/common-sense-3.75.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Bzip2-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Zlib-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/IO-Compress-2.093.tar.gz&lt;br /&gt;
H/HM/HMBRAND/Config-Perl-V-0.31.tgz&lt;br /&gt;
A/AT/ATOOMIC/TimeDate-2.33.tar.gz&lt;br /&gt;
P/PM/PMQS/DB_File-1.853.tar.gz&lt;br /&gt;
H/HU/HURRICUP/Devel-Camelcadedb-v2019.1.tar.gz&lt;br /&gt;
P/PJ/PJCJ/Devel-Cover-1.36.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Devel-PPPort-3.58.tar.gz&lt;br /&gt;
M/MS/MSHELOR/Digest-SHA-6.02.tar.gz&lt;br /&gt;
R/RJ/RJBS/Email-Sender-1.300034.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
Sehr nützlich ist die Kombination aus cpanminus und cpan-outdated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan-outdated | cpanm --sudo&amp;lt;/pre&amp;gt;&lt;br /&gt;
Diese Befehlssequenz aktualisiert alle aktualisierbaren CPAN-Pakete mit Hilfe von cpanminus (als Superuser).&lt;br /&gt;
&lt;br /&gt;
==== cpan ====&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/CPAN &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;] ist der mit jeder Perl-Installation mitgelieferte Client für das CPAN und lässt sich entweder mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;perl -MCPAN -e shell&amp;lt;/pre&amp;gt;&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan&amp;lt;/pre&amp;gt;&lt;br /&gt;
starten. Es wird ein interaktiver Client gestartet; mit &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; kann eine sehr umfangreiche Hilfe aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Ein Modul lässt sich am einfachsten mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cpan install PAKET::NAME&amp;lt;/pre&amp;gt;&lt;br /&gt;
installieren (hier das nicht-existente Paket &amp;lt;code&amp;gt;PAKET::NAME&amp;lt;/code&amp;gt;). &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; eignet sich weniger gut um Module zu installieren oder zu aktualisieren, aber sehr gut um nach Paketen zu suchen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;i /JSON/&amp;lt;/pre&amp;gt;&lt;br /&gt;
findet jedes Paket, das die Zeichenkette &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; im Bereich Autor, Bundle, Distribution oder Modul enthält. Das sind meist viele Ergebnisse, aber liefert einen Überblick &amp;amp;quot;was geht&amp;amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß ist &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; recht störrisch in der Handhabung. Deshalb empfehle ich die Nutzung von cpanminus.&lt;br /&gt;
&lt;br /&gt;
=== OS-Paketmanager ===&lt;br /&gt;
&lt;br /&gt;
==== Debian und Derivate (Ubuntu, Raspbian, etc.) ====&lt;br /&gt;
&lt;br /&gt;
Vom Debian-Projekt werden viele, aber lange nicht alle, Pakete des CPAN auch als Pakete für den eingebauten Paketmanager &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt; [https://packages.debian.org/stable/perl/ bereitsgestellt]. Dort sind momentan etwa 4 000 Pakete verfügbar, d.h. rund 2% der im CPAN verfügbaren Pakete. Es ist nicht immer trivial, ein Paket zu finden. Ein einfacher Fall ist z.B. das Paket &amp;lt;code&amp;gt;Readonly&amp;lt;/code&amp;gt;, der über &amp;lt;code&amp;gt;cpanm Readonly&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;apt-get install libreadonly-perl&amp;lt;/code&amp;gt; installiert werden könnte. Im Allgemeinen kann man sagen, dass sich der Name des &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;-Paketes aus dem Prefix &amp;lt;code&amp;gt;lib&amp;lt;/code&amp;gt;, gefolgt vom Paketnamen in Kleinbuchstaben, bei dem die &amp;lt;code&amp;gt;::&amp;lt;/code&amp;gt; durch &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt; ersetzt wurden, und dem Suffix &amp;lt;code&amp;gt;-perl&amp;lt;/code&amp;gt; zusammensetzt:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! CPAN&lt;br /&gt;
! Debian-Paket&lt;br /&gt;
|-&lt;br /&gt;
| Rose::URI&lt;br /&gt;
| librose-uri-perl&lt;br /&gt;
|-&lt;br /&gt;
| Sah::Schemas::Rinci&lt;br /&gt;
| libsah-schemas-rinci-perl&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Kein Beispiel wäre vollständig ohne Ausnahme, z.B.:&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;libromana-perligata-perl&amp;lt;/code&amp;gt;] installiert das Perl-Paket [https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;Lingua::Romana::Perligata&amp;lt;/code&amp;gt;], müsste nach der selbstgewählten Konvention aber &amp;lt;code&amp;gt;liblingua-romana-perligata-perl&amp;lt;/code&amp;gt; heißen.&lt;br /&gt;
&lt;br /&gt;
Vorteilhaft ist, dass man die Pakete zusammen mit anderen Debian-Paketen automatisch auf dem aktuellen Stand halten kann, z.B. [https://wiki.debian.org/UnattendedUpgrades &amp;lt;code&amp;gt;unattended-upgrades&amp;lt;/code&amp;gt;] - man spart so eine doppelte Implementierung der Updates.&lt;br /&gt;
&lt;br /&gt;
Wiederum von Nachteil ist, dass man mit einer auf ein Release festgelegten Quelle irgendwann auch keine Updates der Perl-Pakete mehr enthält.&lt;br /&gt;
&lt;br /&gt;
==== SuSE Linux ====&lt;br /&gt;
&lt;br /&gt;
YaST bietet aktuell etwa 3 121 der rund 200 000 Pakete in [https://build.opensuse.org/project/show/devel:languages:perl &amp;lt;code&amp;gt;devel:languages:perl&amp;lt;/code&amp;gt;] an, dazu kommen noch einige Community-Pakete mit einer trivial nicht feststellbaren Anzahl an Paketen. Im Paket [https://build.opensuse.org/package/show/devel:languages:perl:CPAN-A/perl-App-cpanminus &amp;lt;code&amp;gt;perl-App-cpanminus&amp;lt;/code&amp;gt;] ist &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; enthalten.&lt;br /&gt;
&lt;br /&gt;
==== RedHat Linux ====&lt;br /&gt;
&lt;br /&gt;
==== MacOS ====&lt;br /&gt;
&lt;br /&gt;
Für MacOS gilt, dass das installierte Perl den &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;-Client und eine Auswahl an Module mitbringt. &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; lässt sich installieren und sollte auch der Weg der Wahl sein. Es ist außerdem möglich, Pakete über [https://www.macports.org/ MacPorts] zu installieren. MacPorts bietet noch weniger Pakete (aktuell 1 797 für Perl 5.26, 1 799 für Perl 5.28) als Debian.&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
&lt;br /&gt;
[https://www.activestate.com/products/perl/downloads/ ActiveState] bietet eine Perl-Distribution an, die bereits mit einigen Module, 214 bei [https://platform.activestate.com/ActiveState/ActivePerl-5.28 Perl 5.28], ausgeliefert wird.&lt;br /&gt;
&lt;br /&gt;
== Empfohlene Pakete ==&lt;br /&gt;
&lt;br /&gt;
Im FHEM-Umfeld werden aktuell rund 120 CPAN-Pakete (mit Sub-Paketen) eingesetzt die keine [https://www.perl.com/article/what-is-the-perl-core-/ Core-Module] sind und ggf. für ein FHEM-Modul [[Meta|nachinstalliert]] werden müssen:&lt;br /&gt;
&lt;br /&gt;
* Authen::OATH&lt;br /&gt;
* AutoLoader&lt;br /&gt;
* B&lt;br /&gt;
* Carp&lt;br /&gt;
* Color&lt;br /&gt;
* Compress::Zlib&lt;br /&gt;
* Convert::Base32&lt;br /&gt;
* Cpanel::JSON::XS&lt;br /&gt;
* Crypt::Argon2&lt;br /&gt;
* Crypt::CBC&lt;br /&gt;
* Crypt::Cipher::AES&lt;br /&gt;
* Crypt::ECB&lt;br /&gt;
* Crypt::Mode::CBC&lt;br /&gt;
* Crypt::MySQL&lt;br /&gt;
* Crypt::NaCl::Sodium&lt;br /&gt;
* Crypt::Rijndael&lt;br /&gt;
* Crypt::Rijndael_PP&lt;br /&gt;
* Crypt::URandom&lt;br /&gt;
* DBI&lt;br /&gt;
* DBI::Const::GetInfoType&lt;br /&gt;
* Data::Dumper&lt;br /&gt;
* Data::UUID&lt;br /&gt;
* Date::Parse&lt;br /&gt;
* DateTime&lt;br /&gt;
* Device::Firmata&lt;br /&gt;
* Device::Firmata::Base&lt;br /&gt;
* Device::Firmata::Constants&lt;br /&gt;
* Device::Firmata::Error&lt;br /&gt;
* Device::Firmata::Language&lt;br /&gt;
* Device::Firmata::Platform&lt;br /&gt;
* Device::Firmata::Protocol&lt;br /&gt;
* Device::SerialPort&lt;br /&gt;
* Device::USB&lt;br /&gt;
* Digest::CRC&lt;br /&gt;
* Digest::SHA1&lt;br /&gt;
* Encode::Detect::Detector&lt;br /&gt;
* Expect&lt;br /&gt;
* File::HomeDir&lt;br /&gt;
* HTML::Entities&lt;br /&gt;
* HTML::Parser&lt;br /&gt;
* HTTP::Cookies&lt;br /&gt;
* HTTP::Daemon&lt;br /&gt;
* HTTP::Headers&lt;br /&gt;
* HTTP::Request&lt;br /&gt;
* HTTP::Request::Common&lt;br /&gt;
* IO::Interface::Simple&lt;br /&gt;
* IO::Socket::Multicast&lt;br /&gt;
* IO::Socket::Multicast6&lt;br /&gt;
* IO::Socket::SSL&lt;br /&gt;
* IO::Socket::Timeout&lt;br /&gt;
* IO::String&lt;br /&gt;
* Image::ExifTool&lt;br /&gt;
* Image::LibRSVG&lt;br /&gt;
* Image::Size&lt;br /&gt;
* Inline&lt;br /&gt;
* JSON&lt;br /&gt;
* JSON::MaybeXS&lt;br /&gt;
* JSON::XS&lt;br /&gt;
* JSON::backportPP&lt;br /&gt;
* JsonMod::JSON::Path::Node&lt;br /&gt;
* LWP&lt;br /&gt;
* LWP::Simple&lt;br /&gt;
* LWP::UserAgent~6&lt;br /&gt;
* Linux::Inotify2&lt;br /&gt;
* LiquidCrystal&lt;br /&gt;
* Lirc::Client&lt;br /&gt;
* List::MoreUtils&lt;br /&gt;
* MIME::Lite&lt;br /&gt;
* MP3::Info&lt;br /&gt;
* MP3::Tag&lt;br /&gt;
* MP3::Tag::CDDB_File&lt;br /&gt;
* MP3::Tag::Cue&lt;br /&gt;
* MP3::Tag::File&lt;br /&gt;
* MP3::Tag::ID3v1&lt;br /&gt;
* MP3::Tag::ID3v2&lt;br /&gt;
* MP3::Tag::ImageExifTool&lt;br /&gt;
* MP3::Tag::ImageSize&lt;br /&gt;
* MP3::Tag::Inf&lt;br /&gt;
* MP3::Tag::LastResort&lt;br /&gt;
* MP3::Tag::ParseData&lt;br /&gt;
* Mail::IMAPClient&lt;br /&gt;
* Mojolicious~5.54&lt;br /&gt;
* Net::Address::IP::Local&lt;br /&gt;
* Net::Bonjour&lt;br /&gt;
* Net::FTPSSL&lt;br /&gt;
* Net::Jabber&lt;br /&gt;
* Net::MQTT::Constants&lt;br /&gt;
* Net::MQTT::Message&lt;br /&gt;
* Net::MQTT::Message::JustMessageId&lt;br /&gt;
* Net::Rendezvous&lt;br /&gt;
* Net::SIP&lt;br /&gt;
* Net::SIP::Packet&lt;br /&gt;
* Net::SMTP::SSL&lt;br /&gt;
* Net::Telnet&lt;br /&gt;
* Net::UPnP::AV::MediaRenderer&lt;br /&gt;
* Net::UPnP::AV::MediaServer&lt;br /&gt;
* Net::UPnP::ControlPoint&lt;br /&gt;
* Net::UPnP::Device&lt;br /&gt;
* Net::UPnP::Service&lt;br /&gt;
* Net::XMPP::Namespaces&lt;br /&gt;
* Nmap::Parser&lt;br /&gt;
* Path::Tiny&lt;br /&gt;
* Paws::Polly&lt;br /&gt;
* Perl::PrereqScanner::NotQuiteLite&lt;br /&gt;
* RPC::XML::Client&lt;br /&gt;
* RPC::XML::Server&lt;br /&gt;
* RiveScript&lt;br /&gt;
* SOAP::Lite&lt;br /&gt;
* Text::Iconv&lt;br /&gt;
* Try::Tiny&lt;br /&gt;
* UPnP::Common&lt;br /&gt;
* UPnP::ControlPoint&lt;br /&gt;
* URI::Escape&lt;br /&gt;
* WWW::Jawbone::Up&lt;br /&gt;
* Win32::SerialPort&lt;br /&gt;
* XML::LibXML&lt;br /&gt;
* XML::Parser::Lite&lt;br /&gt;
&lt;br /&gt;
[https://raw.githubusercontent.com/fhem/doc-wiki/master/DE/Howtos/fhem-cpan-modules.txt Liste als plain text], z.B. um sie bei einer automatisierten Installation verwenden zu können. Die Liste wurde mit &amp;lt;code&amp;gt;Perl::PrereqScanner&amp;lt;/code&amp;gt; aus dem &amp;lt;code&amp;gt;FHEM/&amp;lt;/code&amp;gt;-Verzeichnis erstellt, durch &amp;lt;code&amp;gt;Core::List&amp;lt;/code&amp;gt; gefiltert und mit &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; auf Nicht-CPAN-Module (z.B. &amp;lt;code&amp;gt;FHEM::Meta&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;DevIO&amp;lt;/code&amp;gt;) geprüft.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HOWTOS]] [[Kategorie:Systemadministration]] [[Kategorie:Perl]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=33381</id>
		<title>CPAN</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=CPAN&amp;diff=33381"/>
		<updated>2020-06-13T18:16:40Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Die Seite wurde neu angelegt: „Das CPAN, Comprehensive Perl Archive Network, ist ein weltweit verteiltes Netzwerk für Perl-Module, das seit 1995 besteht und aktuell etwa 200 000 Module umfa…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das CPAN, Comprehensive Perl Archive Network, ist ein weltweit verteiltes Netzwerk für Perl-Module, das seit 1995 besteht und aktuell etwa 200 000 Module umfasst.&lt;br /&gt;
&lt;br /&gt;
Siehe auch hier eine [https://www.cpan.org/modules/INSTALL.html Zusammenfassung des CPAN-Projektes].&lt;br /&gt;
==Clients==&lt;br /&gt;
===Plattformunabhängig===&lt;br /&gt;
Das CPAN bietet drei plattformunabhängige Clients an, von denen zwei hier beschrieben werden. Die &#039;&#039;Empfehlung&#039;&#039; ist, &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; zu nutzen.&lt;br /&gt;
====cpanminus====&lt;br /&gt;
[https://metacpan.org/pod/distribution/App-cpanminus/bin/cpanm cpanminus] (&amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt;) ist der bevorzugte Weg, wie CPAN-Pakete installiert werden sollten. cpan-minus ist, wie &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; ein CPAN-Paket, das aber auch für viele Betriebssystem als fertiges Paket portiert wurde.&lt;br /&gt;
&lt;br /&gt;
cpan-minus bietet einen [http://cpanmin.us/ Quickstart] an, der auf jedem System läuft, auf dem Perl installiert ist. Dazu muss folgender Befehl auf der Kommandozeile ausgeführt werden:&amp;lt;pre&amp;gt;curl -L https://cpanmin.us | perl - App::cpanminus&amp;lt;/pre&amp;gt;Aus Sicherheitsgründen sollte vor Ausführung des Befehls überprüft werden, was unter [http://cpanmin.us/ cpanmin.us] zu finden ist, da ggf. Schadcode unbemerkt eingeschmuggelt werden könnte.&lt;br /&gt;
&lt;br /&gt;
Ist der Client &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; installiert, kann mit&amp;lt;pre&amp;gt;cpanm Paket::Name&amp;lt;/pre&amp;gt;ein Paket (in diesem Falle das nicht-existende Paket &amp;lt;code&amp;gt;Paket::Name&amp;lt;/code&amp;gt;) installiert werden. Die Option &amp;lt;code&amp;gt;--sudo&amp;lt;/code&amp;gt; sorgt dafür, dass cpanminus die Installation als Superuser versucht (ggf. muss ein Passwort eingegeben werden).&lt;br /&gt;
====Exkurs: cpan-outdated====&lt;br /&gt;
Das Paket [https://metacpan.org/pod/distribution/cpan-outdated/script/cpan-outdated &amp;lt;code&amp;gt;cpan-outdated&amp;lt;/code&amp;gt;] erzeugt eine cpanminus-kompatible Liste an CPAN-Paketen, die aktualisiert werden können, z.B.&amp;lt;pre&amp;gt;$ cpan-outdated &lt;br /&gt;
A/AN/ANDK/CPAN-2.27.tar.gz&lt;br /&gt;
L/LE/LEONT/Test-Harness-3.42.tar.gz&lt;br /&gt;
B/BI/BINGOS/Archive-Tar-2.36.tar.gz&lt;br /&gt;
T/TO/TODDR/autodie-2.32.tar.gz&lt;br /&gt;
R/RU/RURBAN/B-Debug-1.26.tar.gz&lt;br /&gt;
I/IL/ILMARI/bareword-filehandles-0.007.tar.gz&lt;br /&gt;
P/PJ/PJACKLAM/bignum-0.51.tar.gz&lt;br /&gt;
X/XS/XSAWYERX/Carp-1.50.tar.gz&lt;br /&gt;
L/LE/LEEJO/CGI-4.47.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Clone-0.45.tar.gz&lt;br /&gt;
M/ML/MLEHMANN/common-sense-3.75.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Bzip2-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/Compress-Raw-Zlib-2.093.tar.gz&lt;br /&gt;
P/PM/PMQS/IO-Compress-2.093.tar.gz&lt;br /&gt;
H/HM/HMBRAND/Config-Perl-V-0.31.tgz&lt;br /&gt;
A/AT/ATOOMIC/TimeDate-2.33.tar.gz&lt;br /&gt;
P/PM/PMQS/DB_File-1.853.tar.gz&lt;br /&gt;
H/HU/HURRICUP/Devel-Camelcadedb-v2019.1.tar.gz&lt;br /&gt;
P/PJ/PJCJ/Devel-Cover-1.36.tar.gz&lt;br /&gt;
A/AT/ATOOMIC/Devel-PPPort-3.58.tar.gz&lt;br /&gt;
M/MS/MSHELOR/Digest-SHA-6.02.tar.gz&lt;br /&gt;
R/RJ/RJBS/Email-Sender-1.300034.tar.gz&amp;lt;/pre&amp;gt;Sehr nützlich ist die Kombination aus cpanminus und cpan-outdated:&amp;lt;pre&amp;gt;cpan-outdated | cpanm --sudo&amp;lt;/pre&amp;gt;Diese Befehlssequenz aktualisiert alle aktualisierbaren CPAN-Pakete mit Hilfe von cpanminus (als Superuser).&lt;br /&gt;
====cpan====&lt;br /&gt;
[https://metacpan.org/pod/CPAN &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;] ist der mit jeder Perl-Installation mitgelieferte Client für das CPAN und lässt sich entweder mit&amp;lt;pre&amp;gt;perl -MCPAN -e shell&amp;lt;/pre&amp;gt;oder&amp;lt;pre&amp;gt;cpan&amp;lt;/pre&amp;gt;starten. Es wird ein interaktiver Client gestartet; mit &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; kann eine sehr umfangreiche Hilfe aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Ein Modul lässt sich am einfachsten mit&amp;lt;pre&amp;gt;cpan install PAKET::NAME&amp;lt;/pre&amp;gt;installieren (hier das nicht-existente Paket &amp;lt;code&amp;gt;PAKET::NAME&amp;lt;/code&amp;gt;). &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; eignet sich weniger gut um Module zu installieren oder zu aktualisieren, aber sehr gut um nach Paketen zu suchen:&amp;lt;pre&amp;gt;i /JSON/&amp;lt;/pre&amp;gt;findet jedes Paket, das die Zeichenkette &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; im Bereich Autor, Bundle, Distribution oder Modul enthält. Das sind meist viele Ergebnisse, aber liefert einen Überblick &amp;amp;quot;was geht&amp;amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß ist &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt; recht störrisch in der Handhabung. Deshalb empfehle ich die Nutzung von cpanminus.&lt;br /&gt;
===OS-Paketmanager===&lt;br /&gt;
====Debian und Derivate (Ubuntu, Raspbian, etc.)====&lt;br /&gt;
Vom Debian-Projekt werden viele, aber lange nicht alle, Pakete des CPAN auch als Pakete für den eingebauten Paketmanager &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt; [https://packages.debian.org/stable/perl/ bereitsgestellt]. Dort sind momentan etwa 4 000 Pakete verfügbar, d.h. rund 2% der im CPAN verfügbaren Pakete. Es ist nicht immer trivial, ein Paket zu finden. Ein einfacher Fall ist z.B. das Paket &amp;lt;code&amp;gt;Readonly&amp;lt;/code&amp;gt;, der über &amp;lt;code&amp;gt;cpanm Readonly&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;apt-get install libreadonly-perl&amp;lt;/code&amp;gt; installiert werden könnte. Im Allgemeinen kann man sagen, dass sich der Name des &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt;-Paketes aus dem Prefix &amp;lt;code&amp;gt;lib&amp;lt;/code&amp;gt;, gefolgt vom Paketnamen in Kleinbuchstaben, bei dem die &amp;lt;code&amp;gt;::&amp;lt;/code&amp;gt; durch &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt; ersetzt wurden, und dem Suffix &amp;lt;code&amp;gt;-perl&amp;lt;/code&amp;gt; zusammensetzt:&lt;br /&gt;
{|&lt;br /&gt;
!CPAN&lt;br /&gt;
!Debian-Paket&lt;br /&gt;
|-&lt;br /&gt;
|Rose::URI&lt;br /&gt;
|librose-uri-perl&lt;br /&gt;
|-&lt;br /&gt;
|Sah::Schemas::Rinci&lt;br /&gt;
|libsah-schemas-rinci-perl&lt;br /&gt;
|}Kein Beispiel wäre vollständig ohne Ausnahme, z.B.:&lt;br /&gt;
&lt;br /&gt;
[https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;libromana-perligata-perl&amp;lt;/code&amp;gt;] installiert das Perl-Paket [https://metacpan.org/pod/distribution/Lingua-Romana-Perligata/lib/Lingua/Romana/Perligata.pm &amp;lt;code&amp;gt;Lingua::Romana::Perligata&amp;lt;/code&amp;gt;], müsste nach der selbstgewählten Konvention aber &amp;lt;code&amp;gt;liblingua-romana-perligata-perl&amp;lt;/code&amp;gt; heißen.&lt;br /&gt;
&lt;br /&gt;
Vorteilhaft ist, dass man die Pakete zusammen mit anderen Debian-Paketen automatisch auf dem aktuellen Stand halten kann, z.B. [https://wiki.debian.org/UnattendedUpgrades &amp;lt;code&amp;gt;unattended-upgrades&amp;lt;/code&amp;gt;] - man spart so eine doppelte Implementierung der Updates.&lt;br /&gt;
&lt;br /&gt;
Wiederum von Nachteil ist, dass man mit einer auf ein Release festgelegten Quelle irgendwann auch keine Updates der Perl-Pakete mehr enthält.&lt;br /&gt;
====SuSE Linux====&lt;br /&gt;
YaST bietet aktuell etwa 3 121 der rund 200 000 Pakete in [https://build.opensuse.org/project/show/devel:languages:perl &amp;lt;code&amp;gt;devel:languages:perl&amp;lt;/code&amp;gt;] an, dazu kommen noch einige Community-Pakete mit einer trivial nicht feststellbaren Anzahl an Paketen. Im Paket [https://build.opensuse.org/package/show/devel:languages:perl:CPAN-A/perl-App-cpanminus &amp;lt;code&amp;gt;perl-App-cpanminus&amp;lt;/code&amp;gt;] ist &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; enthalten.&lt;br /&gt;
====RedHat Linux====&lt;br /&gt;
====MacOS====&lt;br /&gt;
Für MacOS gilt, dass das installierte Perl den &amp;lt;code&amp;gt;cpan&amp;lt;/code&amp;gt;-Client und eine Auswahl an Module mitbringt. &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; lässt sich installieren und sollte auch der Weg der Wahl sein. Es ist außerdem möglich, Pakete über [https://www.macports.org/ MacPorts] zu installieren. MacPorts bietet noch weniger Pakete (aktuell 1 797 für Perl 5.26, 1 799 für Perl 5.28) als Debian.&lt;br /&gt;
====Windows====&lt;br /&gt;
[https://www.activestate.com/products/perl/downloads/ ActiveState] bietet eine Perl-Distribution an, die bereits mit einigen Module, 214 bei [https://platform.activestate.com/ActiveState/ActivePerl-5.28 Perl 5.28], ausgeliefert wird.&lt;br /&gt;
==Empfohlene Pakete==&lt;br /&gt;
Im FHEM-Umfeld werden aktuell rund 120 CPAN-Pakete (mit Sub-Paketen) eingesetzt die keine [https://www.perl.com/article/what-is-the-perl-core-/ Core-Module] sind und ggf. für ein FHEM-Modul [[Meta|nachinstalliert]] werden müssen:&lt;br /&gt;
*Authen::OATH&lt;br /&gt;
*AutoLoader&lt;br /&gt;
*B&lt;br /&gt;
*Carp&lt;br /&gt;
*Color&lt;br /&gt;
*Compress::Zlib&lt;br /&gt;
*Convert::Base32&lt;br /&gt;
*Cpanel::JSON::XS&lt;br /&gt;
*Crypt::Argon2&lt;br /&gt;
*Crypt::CBC&lt;br /&gt;
*Crypt::Cipher::AES&lt;br /&gt;
*Crypt::ECB&lt;br /&gt;
*Crypt::Mode::CBC&lt;br /&gt;
*Crypt::MySQL&lt;br /&gt;
*Crypt::NaCl::Sodium&lt;br /&gt;
*Crypt::Rijndael&lt;br /&gt;
*Crypt::Rijndael_PP&lt;br /&gt;
*Crypt::URandom&lt;br /&gt;
*DBI&lt;br /&gt;
*DBI::Const::GetInfoType&lt;br /&gt;
*Data::Dumper&lt;br /&gt;
*Data::UUID&lt;br /&gt;
*Date::Parse&lt;br /&gt;
*DateTime&lt;br /&gt;
*Device::Firmata&lt;br /&gt;
*Device::Firmata::Base&lt;br /&gt;
*Device::Firmata::Constants&lt;br /&gt;
*Device::Firmata::Error&lt;br /&gt;
*Device::Firmata::Language&lt;br /&gt;
*Device::Firmata::Platform&lt;br /&gt;
*Device::Firmata::Protocol&lt;br /&gt;
*Device::SerialPort&lt;br /&gt;
*Device::USB&lt;br /&gt;
*Digest::CRC&lt;br /&gt;
*Digest::SHA1&lt;br /&gt;
*Encode::Detect::Detector&lt;br /&gt;
*Expect&lt;br /&gt;
*File::HomeDir&lt;br /&gt;
*HTML::Entities&lt;br /&gt;
*HTML::Parser&lt;br /&gt;
*HTTP::Cookies&lt;br /&gt;
*HTTP::Daemon&lt;br /&gt;
*HTTP::Headers&lt;br /&gt;
*HTTP::Request&lt;br /&gt;
*HTTP::Request::Common&lt;br /&gt;
*IO::Interface::Simple&lt;br /&gt;
*IO::Socket::Multicast&lt;br /&gt;
*IO::Socket::Multicast6&lt;br /&gt;
*IO::Socket::SSL&lt;br /&gt;
*IO::Socket::Timeout&lt;br /&gt;
*IO::String&lt;br /&gt;
*Image::ExifTool&lt;br /&gt;
*Image::LibRSVG&lt;br /&gt;
*Image::Size&lt;br /&gt;
*Inline&lt;br /&gt;
*JSON&lt;br /&gt;
*JSON::MaybeXS&lt;br /&gt;
*JSON::XS&lt;br /&gt;
*JSON::backportPP&lt;br /&gt;
*JsonMod::JSON::Path::Node&lt;br /&gt;
*LWP&lt;br /&gt;
*LWP::Simple&lt;br /&gt;
*LWP::UserAgent~6&lt;br /&gt;
*Linux::Inotify2&lt;br /&gt;
*LiquidCrystal&lt;br /&gt;
*Lirc::Client&lt;br /&gt;
*List::MoreUtils&lt;br /&gt;
*MIME::Lite&lt;br /&gt;
*MP3::Info&lt;br /&gt;
*MP3::Tag&lt;br /&gt;
*MP3::Tag::CDDB_File&lt;br /&gt;
*MP3::Tag::Cue&lt;br /&gt;
*MP3::Tag::File&lt;br /&gt;
*MP3::Tag::ID3v1&lt;br /&gt;
*MP3::Tag::ID3v2&lt;br /&gt;
*MP3::Tag::ImageExifTool&lt;br /&gt;
*MP3::Tag::ImageSize&lt;br /&gt;
*MP3::Tag::Inf&lt;br /&gt;
*MP3::Tag::LastResort&lt;br /&gt;
*MP3::Tag::ParseData&lt;br /&gt;
*Mail::IMAPClient&lt;br /&gt;
*Mojolicious~5.54&lt;br /&gt;
*Net::Address::IP::Local&lt;br /&gt;
*Net::Bonjour&lt;br /&gt;
*Net::FTPSSL&lt;br /&gt;
*Net::Jabber&lt;br /&gt;
*Net::MQTT::Constants&lt;br /&gt;
*Net::MQTT::Message&lt;br /&gt;
*Net::MQTT::Message::JustMessageId&lt;br /&gt;
*Net::Rendezvous&lt;br /&gt;
*Net::SIP&lt;br /&gt;
*Net::SIP::Packet&lt;br /&gt;
*Net::SMTP::SSL&lt;br /&gt;
*Net::Telnet&lt;br /&gt;
*Net::UPnP::AV::MediaRenderer&lt;br /&gt;
*Net::UPnP::AV::MediaServer&lt;br /&gt;
*Net::UPnP::ControlPoint&lt;br /&gt;
*Net::UPnP::Device&lt;br /&gt;
*Net::UPnP::Service&lt;br /&gt;
*Net::XMPP::Namespaces&lt;br /&gt;
*Nmap::Parser&lt;br /&gt;
*Path::Tiny&lt;br /&gt;
*Paws::Polly&lt;br /&gt;
*Perl::PrereqScanner::NotQuiteLite&lt;br /&gt;
*RPC::XML::Client&lt;br /&gt;
*RPC::XML::Server&lt;br /&gt;
*RiveScript&lt;br /&gt;
*SOAP::Lite&lt;br /&gt;
*Text::Iconv&lt;br /&gt;
*Try::Tiny&lt;br /&gt;
*UPnP::Common&lt;br /&gt;
*UPnP::ControlPoint&lt;br /&gt;
*URI::Escape&lt;br /&gt;
*WWW::Jawbone::Up&lt;br /&gt;
*Win32::SerialPort&lt;br /&gt;
*XML::LibXML&lt;br /&gt;
*XML::Parser::Lite&lt;br /&gt;
[https://raw.githubusercontent.com/fhem/doc-wiki/master/DE/Howtos/fhem-cpan-modules.txt Liste als plain text], z.B. um sie bein einer automatisierten Installation verwenden zu können. Die Liste wurde mit &amp;lt;code&amp;gt;Perl::PrereqScanner&amp;lt;/code&amp;gt; aus dem &amp;lt;code&amp;gt;FHEM/&amp;lt;/code&amp;gt;-Verzeichnis erstellt, durch &amp;lt;code&amp;gt;Core::List&amp;lt;/code&amp;gt; gefiltert und mit &amp;lt;code&amp;gt;cpanm&amp;lt;/code&amp;gt; auf Nicht-CPAN-Module (z.B. &amp;lt;code&amp;gt;FHEM::Meta&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;DevIO&amp;lt;/code&amp;gt;) geprüft.&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=DevelopmentModuleIntro&amp;diff=33360</id>
		<title>DevelopmentModuleIntro</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=DevelopmentModuleIntro&amp;diff=33360"/>
		<updated>2020-06-07T14:41:06Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Moved sub paragraph to a real one&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hinweis|Dieser Text ist in Arbeit und muss noch an einigen Stellen ergänzt werden. }}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Um neue Geräte, Dienste, o.ä. in FHEM verfügbar zu machen, kann man ein eigenes Modul in Perl schreiben. Ein Modul wird in FHEM automatisch geladen, wenn ein entsprechendes Device in FHEM definiert wird. Das Modul ermöglicht eine spezifische Kommunikation mit einem physikalischen Gerät, stellt Ergebnisse (&amp;quot;Readings&amp;quot;) und Events innerhalb von FHEM zur Verfügung und erlaubt es, das Gerät mit &amp;quot;Set&amp;quot;-/&amp;quot;Get&amp;quot;-Befehlen zu beeinflussen. Dieser Artikel soll den Einstieg in die Entwicklung eigener Module erleichtern.&lt;br /&gt;
&lt;br /&gt;
Mit dem FHEM-Befehl &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; werden Devices in FHEM basierend auf einem Modul definiert. Dieser Befehl sorgt dafür, dass ein neues Modul bei Bedarf geladen und initialisiert wird. Ein gutes Beispiel ist hierbei die zentrale Konfigurationsdatei &amp;quot;fhem.cfg&amp;quot; in der sämtliche Devices in Form von &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Statements gespeichert sind.&lt;br /&gt;
&lt;br /&gt;
Damit das funktioniert müssen der Name des Moduls und der Name der [[#X_Initialize|Initialisierungsfunktion]]  identisch sein. Das folgende Beispiel soll dies verdeutlichen:&lt;br /&gt;
&lt;br /&gt;
Ein Jeelink USB-Stick könnte beispielsweise mit dem Befehl &amp;lt;code&amp;gt;define JeeLink1 &#039;&#039;JeeLink&#039;&#039; /dev/ttyUSB0@57600&amp;lt;/code&amp;gt; definiert werden.&lt;br /&gt;
&lt;br /&gt;
In fhem.pl wird der &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Befehl verarbeitet und geprüft, ob ein Modul mit dem Namen &amp;quot;JeeLink&amp;quot; schon geladen ist. Falls nicht, wird ein Modul mit Namen XY_JeeLink.pm im Modulverzeichnis (z.B. /opt/fhem/FHEM) gesucht und, falls vorhanden, anschließend geladen. &lt;br /&gt;
Danach wird die Funktion &amp;lt;code&amp;gt;&#039;&#039;JeeLink&#039;&#039;_Initialize()&amp;lt;/code&amp;gt; aufgerufen um das Modul in FHEM zu registrieren. Eine Moduldatei muss dazu eine Funktion &amp;lt;code&amp;gt;&#039;&#039;&amp;amp;lt;Modulname&amp;amp;gt;&#039;&#039;_Initialize()&amp;lt;/code&amp;gt; enthalten. Durch den Aufruf dieser Funktion wird FHEM mitgeteilt, welche Funktionalitäten dieses Modul unterstützt und durch welche Perl-Funktionen im Modul selbst diese ausimplementiert werden.&lt;br /&gt;
&lt;br /&gt;
In der Initialisierungsfunktion des Moduls werden die Namen aller weiteren Perl-Funktionen des Moduls, die von fhem.pl aus aufgerufen werden, bekannt gemacht. Dazu wird für jedes Modul ein eigener Hash (genauer &amp;quot;Modul-Hash&amp;quot;) mit entsprechenden Werten gefüllt, der in fhem.pl für jedes Modul entsprechend abgelegt wird. Dadurch weiß FHEM wie dieses Modul anzusprechen ist.&lt;br /&gt;
&lt;br /&gt;
== Grundlegender Aufbau eines Moduls ==&lt;br /&gt;
&lt;br /&gt;
=== Dateiname ===&lt;br /&gt;
&lt;br /&gt;
Ein FHEM-Modul wird als Perl-Modul mit der Dateiendung *.pm abgespeichert. Der Dateiname folgt dabei folgendem Schema:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;&#039;&#039;[&#039;&#039;&#039;Schlüsselnummer&#039;&#039;&#039;]&#039;&#039;&amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;_&amp;lt;/font&amp;gt;&#039;&#039;[&#039;&#039;&#039;Modulname&#039;&#039;&#039;]&#039;&#039;&amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;.pm&amp;lt;/font&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Schlüsselnummer&#039;&#039;&#039; - Eine zweistellige Zahl zwischen 00 - 99. Die Schlüsselnummer hat aktuell keine technische Relevanz mehr. In früheren FHEM-Versionen ist sie relevant für [[#Zweistufiges_Modell_f.C3.BCr_Module|zweistufige Module]] (Reihenfolge für [[DevelopmentModuleAPI#Dispatch|Dispatch()]] um logische Module zu prüfen). Die allgemeine Empfehlung ist hierbei eine Schlüsselnummer eines Moduls zu verwenden, welches eine ähnliche Funktionalität bietet. Die Schlüsselnummer 99 hat hierbei eine besondere Bedeutung, da alle Module mit dieser Schlüsselnummer beim Start von FHEM automatisch geladen werden, selbst, wenn sie in der Konfiguration nicht verwendet werden. Daher wird für myUtils 99 als Schlüsselnummer verwendet (99_myUtils.pm). Module mit der Schlüsselnummer 99 werden im SVN nicht akzeptiert (siehe [[SVN Nutzungsregeln]])&lt;br /&gt;
* &#039;&#039;&#039;Modulname&#039;&#039;&#039; - Der Name des Moduls wie er in FHEM bei dem Anlegen einer Gerätedefinition zu verwenden ist. Der Modulname sollte nur aus den folgenden möglichen Zeichen bestehen: Groß-/Kleinbuchstaben, Zahlen sowie Unterstrich (_)&lt;br /&gt;
&lt;br /&gt;
=== Inhaltlicher Aufbau ===&lt;br /&gt;
&lt;br /&gt;
Ein Modul ist inhaltlich in folgende Abschnitte unterteilt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
#  72_MYMODULE.pm &lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
package main;&lt;br /&gt;
&lt;br /&gt;
# Laden evtl. abhängiger Perl- bzw. FHEM-Hilfsmodule&lt;br /&gt;
use HttpUtils;&lt;br /&gt;
use [...]&lt;br /&gt;
&lt;br /&gt;
# FHEM Modulfunktionen&lt;br /&gt;
&lt;br /&gt;
sub MYMODULE_Initialize() {&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub MYMODULE_Define() {&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
# Eval-Rückgabewert für erfolgreiches&lt;br /&gt;
# Laden des Moduls&lt;br /&gt;
1;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Beginn der Commandref&lt;br /&gt;
&lt;br /&gt;
=pod&lt;br /&gt;
=item [helper|device|command]&lt;br /&gt;
=item summary Kurzbeschreibung in Englisch was MYMODULE steuert/unterstützt&lt;br /&gt;
=item summary_DE Kurzbeschreibung in Deutsch was MYMODULE steuert/unterstützt&lt;br /&gt;
&lt;br /&gt;
=begin html&lt;br /&gt;
 Englische Commandref in HTML&lt;br /&gt;
=end html&lt;br /&gt;
&lt;br /&gt;
=begin html_DE&lt;br /&gt;
 Deutsche Commandref in HTML&lt;br /&gt;
=end html&lt;br /&gt;
&lt;br /&gt;
# Ende der Commandref&lt;br /&gt;
=cut&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man kann hierbei von folgender Reihenfolge sprechen:&lt;br /&gt;
&lt;br /&gt;
# Perl-Code, welcher das Modul implementiert&lt;br /&gt;
# Die Zeile &amp;lt;code&amp;gt;1;&amp;lt;/code&amp;gt; nachdem der Perl-Code abgeschlossen ist. Dies dient FHEM der Erkennung, dass das Modul erfolgreich und vollständig geladen wurde. Sollte diese Zeile nicht enthalten sein, wird FHEM beim Laden des Moduls die Fehlermeldung &amp;lt;code&amp;gt;Error:Modul 72_MYMODULE deactivated&amp;lt;/code&amp;gt; in das Logfile schreiben.&lt;br /&gt;
# Commandref zur Dokumentation des Moduls. Diese Dokumentation soll dem User die möglichen Befehle/Attribute/Readings/Events vermitteln. Weitere Informationen und Hinweise findet man in den [[Guidelines zur Dokumentation]].&lt;br /&gt;
&lt;br /&gt;
== Der Hash einer Geräteinstanz ==&lt;br /&gt;
Eine Besonderheit in Perl sind [http://de.wikipedia.org/wiki/Assoziatives_Array#Perl assoziative Arrays], (nicht ganz richtig als &amp;quot;Hash&amp;quot; bezeichnet) in denen die Adressierung nicht über eine Zählvariable erfolgt, sondern über einen beliebigen String. Die internen Abläufe bei der Adressierung führen dazu, dass die Speicherung in und der Abruf aus Hashes relativ langsam ist.&lt;br /&gt;
&lt;br /&gt;
Der zentrale Speicherort für Informationen einer Geräteinstanz bei FHEM ist ein solcher Hash, der seinerseits in fhem.pl von einem globalen Hash referenziert wird. &lt;br /&gt;
&lt;br /&gt;
In fhem.pl werden alle Gerätedefinitionen in dem globalen Hash &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; abgelegt. Der Inhalt von &amp;lt;code&amp;gt;$defs{&#039;&#039;&amp;amp;lt;Name&amp;amp;gt;&#039;&#039;}&amp;lt;/code&amp;gt; in fhem.pl verweist dabei auf den Hash der Geräteinstanz in Form einer Hashreferenz. Diesen Verweis (also nur die Adresse) bekommen die Funktionen eines Moduls übergeben (i.d.R. als &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; bezeichnet), welche direkt von fhem.pl aufgerufen werden. In dem Hash stehen beispielsweise die internen Werte des Geräts, die im Frontend als &amp;quot;Internals&amp;quot; angezeigt werden, sowie die Readings des Geräts. &lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
*&amp;lt;code&amp;gt;$hash-&amp;gt;{NAME}&amp;lt;/code&amp;gt; enthält den Namen der Geräteinstanz, &lt;br /&gt;
*&amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt; enthält die Typbezeichnung des Geräts (Modulname)&lt;br /&gt;
&lt;br /&gt;
==Ausführung von Modulen==&lt;br /&gt;
FHEM arbeitet intern nicht parallel, sondern arbeitet alle Aufgaben seriell nacheinander kontinuierlich ab. Daher wäre es ungünstig, wenn Module Daten von einem physikalischen Gerät abfragen wollen und dabei innerhalb der selben Funktion auf die Antwort des Geräts warten. In dieser Zeit, in der FHEM auf die Antwort des Gerätes warten muss, wäre der Rest von FHEM blockiert. Da immer nur eine Aufgabe zur selben Zeit bearbeitet wird, müssen alle weiteren Aufgaben solange warten. Eine Datenkommunikation innerhalb eines Moduls sollte daher immer ohne Blockierung erfolgen. Dadurch kann FHEM die Wartezeit effizient für andere Aufgaben nutzen um bspw. anstehende Daten für andere Module zu verarbeiten. Es gibt in FHEM entsprechende Mechanismen, welche eine &amp;quot;Non-Blocking&amp;quot;-Kommunikation über verschiedene Wege (z.B. seriell, HTTP, TCP, ...) ermöglichen.&lt;br /&gt;
&lt;br /&gt;
Dafür werden in FHEM zwei zentrale Listen gepflegt, in der die Filedeskriptoren der geöffneten Kommunikatonsverbindungen gespeichert sind. Auf Linux- bzw. Unix-basierten Plattformen wird der select-Befehl des Betriebssystems verwendet um Filedeskriptoren auf lesbare Daten zu überprüfen. In FHEM gibt es dazu eine Liste (&amp;lt;code&amp;gt;%selectlist&amp;lt;/code&amp;gt;), in der die Filedeskriptoren sämtlicher Geräte (z.B. serielle Verbindung, TCP-Verbindung, etc.) gespeichert sind. &lt;br /&gt;
&lt;br /&gt;
In der zentralen Schleife (Main-Loop) von fhem.pl wird mit &amp;lt;code&amp;gt;select()&amp;lt;/code&amp;gt; überwacht, ob über eine der geöffneten Schnittstellen Daten zum Lesen anstehen. Wenn dies der Fall ist, dann wird die Lesefunktion ([[#X_Read|X_Read]]) des zuständigen Moduls aufgerufen, damit es die Daten entgegennimmt und verarbeitet. Anschließend wird die Schleife weiter ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Auf Windows-Systemen funktioniert dies anders. Hier können USB/Seriell-Geräte nicht per &amp;lt;code&amp;gt;select()&amp;lt;/code&amp;gt; überwacht werden. In FHEM unter Windows werden daher diese Schnittstellen kontinuierlich abgefragt ob Daten bereitstehen. Dafür müssen Module zusätzlich zur Lesefunktion eine Abfragefunktion ([[#X_Ready|X_Ready]]) implementieren, welche prüft, ob Daten zum Lesen anstehen. Auch auf Linux/Unix-Plattformen hat diese Funktion eine Aufgabe. Falls nämlich eine Schnittstelle ausfällt, beziehungsweise ein CUL oder USB-zu-Seriell Adapter ausgesteckt wird, dann wird über diese Funktion regelmäßig geprüft ob die Schnittstelle wieder verfügbar wird.&lt;br /&gt;
&lt;br /&gt;
Innerhalb der eigentlichen Lesefunktion (X_Read) werden dann die Daten vom zugehörigen Gerät gelesen, das nötige Protokoll implementiert um die Daten zu interpretieren und Werte in Readings geschrieben.&lt;br /&gt;
&lt;br /&gt;
Auch wenn von einem Anwender über einen Get-Befehl Daten aktiv von einem Gerät angefordert werden, sollte nicht blockierend gewartet werden. Eine asynchrone Ausgabe, sobald das Ergebnis vorliegt, ist über [[DevelopmentModuleAPI#asyncOutput|asyncOutput()]] möglich. Siehe {{Link2Forum|Topic=43771|Message=357870|LinkText=Beschreibung}} und {{Link2Forum|Topic=43771|Message=360935|LinkText=Beispiel}}. Weitere Anwendungsbeispiele finden sich im  {{Link2Forum|Topic=43052|Message=353477|LinkText=PLEX Modul}} und im überarbeiteten und nicht-blockierenden {{Link2Forum|Topic=42771|Message=348498|LinkText=SYSSTAT Modul}}.&lt;br /&gt;
&lt;br /&gt;
== Wichtige globale Variablen aus fhem.pl ==&lt;br /&gt;
&lt;br /&gt;
FHEM arbeitet mit einer Vielzahl an internen Variablen. Die nun folgenden aufgelisteten Variablen sind die wichtigsten, welche man im Rahmen der Modulprogrammierung kennen sollte:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$init_done&amp;lt;/code&amp;gt; || Dient der Erkennung für fhem.pl sowie den Modulen, ob FHEM den Initialisierungsvorgang abgeschlossen hat. Beim Starten von FHEM ist &amp;lt;code&amp;gt;$init_done&amp;lt;/code&amp;gt; gleich &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Erst, wenn das Einlesen der Konfiguration, sowie des State-Files (Readings) abgeschlossen ist, wird &amp;lt;code&amp;gt;$init_done&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; gesetzt.&lt;br /&gt;
Das gleiche Verfahren wird auch bei dem Befehl &amp;lt;code&amp;gt;rereadcfg&amp;lt;/code&amp;gt; angewandt. Während &amp;lt;code&amp;gt;rereadcfg&amp;lt;/code&amp;gt; ausgeführt wird (Konfiguration löschen, neu einlesen), ist &amp;lt;code&amp;gt;$init_done&amp;lt;/code&amp;gt; gleich &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Dies ist insbesondere in der [[#X_Define|Define]]-Funktion eines Moduls relevant. Durch eine Prüfung auf &amp;lt;code&amp;gt;$init_done&amp;lt;/code&amp;gt; kann man erkennen, ob eine Definition von Hand (&amp;lt;code&amp;gt;$init_done&amp;lt;/code&amp;gt; = 1) oder im Rahmen der Initialisierung (FHEM Start / Rereadcfg =&amp;gt; &amp;lt;code&amp;gt;$init_done&amp;lt;/code&amp;gt; = 0) erfolgte. Während der Initialisierung stehen bspw. die gesetzten Attribute der Definition noch nicht zur Verfügung und können daher nicht ausgewertet werden (siehe . &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%attr&amp;lt;/code&amp;gt; || In &amp;lt;code&amp;gt;%attr&amp;lt;/code&amp;gt; werden sämtliche gesetzten Attribute aller Geräte gespeichert. Diese Datenstruktur wird generell durch den &amp;lt;code&amp;gt;attr&amp;lt;/code&amp;gt;-Befehl verwaltet. Hierbei wird einem Gerätenamen eine Mehrzahl an Attributnamen mit einem Wert zugeordnet. Attribut-Inhalte können über die Funktion [[DevelopmentModuleAPI#AttrVal|AttrVal()]] ausgelesen werden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%cmds&amp;lt;/code&amp;gt; || In &amp;lt;code&amp;gt;%cmds&amp;lt;/code&amp;gt; wird jedem in FHEM existierendem Befehl die entsprechende Funktion zugewiesen, welche diesen Befehl umsetzt. Module können durch das Eintragen eines Befehlsnamen samt Funktion in &amp;lt;code&amp;gt;%cmds&amp;lt;/code&amp;gt; über die [[#X_Initialize|Initialize]]-Funktion eines Moduls einen (oder mehrere) eigene Befehle in FHEM registrieren.&lt;br /&gt;
&lt;br /&gt;
Die Struktur ist dabei wiefolgt:&lt;br /&gt;
&lt;br /&gt;
  $cmds{&#039;&#039;&amp;amp;lt;Befehlsname&amp;amp;gt;&#039;&#039;} = {  Fn  =&amp;gt; &amp;quot;&#039;&#039;&amp;amp;lt;Funktionsname&amp;amp;gt;&#039;&#039;&amp;quot;,&lt;br /&gt;
                            Hlp =&amp;gt; &amp;quot;&#039;&#039;&amp;amp;lt;Aufrufsyntax&amp;amp;gt;&#039;&#039;&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%data&amp;lt;/code&amp;gt;|| Der eigentliche Zweck von &amp;lt;code&amp;gt;%data&amp;lt;/code&amp;gt; ist dem Nutzer eine Möglichkeit zum Speichern von temporären Daten im globalen Kontext zu ermöglichen. Einige Module verwenden &amp;lt;code&amp;gt;%data&amp;lt;/code&amp;gt; jedoch auch um modul- &amp;amp; geräteübergreifend Daten auszutauschen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt;|| In &amp;lt;code&amp;gt;%defs&amp;lt;/code&amp;gt; werden sämtliche Gerätedefinitionen, bzw. die Hash-Referenzen auf diese, gespeichert. Hier ist jedem Gerätenamen eine Hash-Referenz zugeordnet.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%modules&amp;lt;/code&amp;gt;|| In &amp;lt;code&amp;gt;%modules&amp;lt;/code&amp;gt; sind alle geladenen Module gelistet mit ihren entsprechenden Initialisierungsdaten (Funktionsnamen, Attribut-Listen, spezielle Einstellungen, ...). Hier wird für jeden Modulname der Modul-Hash aus der [[#X_Initialize|Initialize]]-Funktion gespeichert. &lt;br /&gt;
Desweiteren legen viele Module, welche nach dem [[DevelopmentModuleIntro#Zweistufiges_Modell_f.C3.BCr_Module|zweistufigen Modulkonzept]] hier eine Rückwärtszuordnung von Geräteadressen zu Geräte-Hash an.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%readyfnlist&amp;lt;/code&amp;gt;|| In &amp;lt;code&amp;gt;%readyfnlist&amp;lt;/code&amp;gt; sind alle zu prüfenden Verbindungen mit ihrer entsprechendem Geräte-Hash gelistet. FHEM prüft alle hier gelisteten Geräte regelmäßig über eine Aufruf der entsprechenden [[#X_Ready|Ready]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Bei einer Nutzung von dem Hilfsmodul [[DevIo|DevIo.pm]] zum Aufbau einer Kommunikationsverbindung, kümmert sich DevIo selbständig um den entsprechenden Eintrag in &amp;lt;code&amp;gt;%readyfnlist&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%selectlist&amp;lt;/code&amp;gt;|| In &amp;lt;code&amp;gt;%selectlist&amp;lt;/code&amp;gt; sind alle geöffneten Verbindungen mit ihrer entsprechendem Geräte-Hash gelistet. FHEM prüft alle hier gelisteten Geräte, ob der geöffnete Filedeskriptor unter &amp;lt;code&amp;gt;$hash-&amp;gt;{FD}&amp;lt;/code&amp;gt; Daten zum Lesen bereitgestellt hat. Ist dass der Fall, wird die entsprechende [[#X_Read|Read]]-Funktion aufgerufen, um anstehende Daten durch das Modul zu verarbeiten.&lt;br /&gt;
Bei einer Nutzung von dem Hilfsmodul [[DevIo|DevIo.pm]] zum Aufbau einer Kommunikationsverbindung, kümmert sich DevIo selbständig um den entsprechenden Eintrag in &amp;lt;code&amp;gt;%selectlist&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Es gibt durchaus viele weitere globale Variablen, die jedoch für sehr spezielle Anwendungsfälle und z.T. nur einzelne Module gedacht sind und daher hier nicht aufgeführt werden.&lt;br /&gt;
&lt;br /&gt;
== Internals ==&lt;br /&gt;
Daten, die ein Modul im Geräte-Hash speichert nennt man Internals. Sie werden als Unterstruktur des Hashes der jeweiligen Geräteinstanz gespeichert, beispielswiese &amp;lt;code&amp;gt;$hash-&amp;gt;{NAME}&amp;lt;/code&amp;gt; für den Gerätenamen, welcher beim Define-Befehl übergeben wurde und als Internal gespeichert wird. Diese Daten spielen für FHEM eine sehr wichtige Rolle, da sämtliche gerätespezifischen Daten als Internal im Gerätehash gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
Falls Werte wie z.B. ein Intervall nicht über den Define-Befehl gesetzt werden sollen und im Betrieb einfach änderbar sein sollten, ist eine alternative Möglichkeit die Speicherung in so genannten Attributen. Dann würde man den Define-Befehl so implementieren, dass er kein Intervall übergeben bekommt und statt dessen das Interval als Attribut über den Befehl &amp;lt;code&amp;gt;attr&amp;lt;/code&amp;gt; gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
Generell werden alle Werte, welche direkt in der ersten Ebene von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; (Gerätehash) gespeichert werden auf der Detail-Seite einer Definition in der FHEMWEB Oberfläche angezeigt. Es gibt jedoch Ausnahmen:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;$hash-&amp;gt;{helper}{URL}&amp;lt;/code&amp;gt; - Alle Elemente, welche als Unterelement wieder einen Hash besitzen werden nicht in FHEMWEB dargestellt. Typischerweise speichern Module Daten unter &amp;lt;code&amp;gt;$hash-&amp;gt;{helper}&amp;lt;/code&amp;gt; interne Daten zwischen, die für den User nicht relevant sind, sondern nur der internen Verarbeitung dienen.&lt;br /&gt;
* &amp;lt;code&amp;gt;$hash-&amp;gt;{&#039;&#039;&#039;.&#039;&#039;&#039;&amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;ELEMENT&amp;lt;/font&amp;gt;}&amp;lt;/code&amp;gt; - Alle Knoten, welche mit einem Punkt beginnen werden in der FHEMWEB Oberfläche nicht angezeigt. Man kann diese Daten jedoch beim Aufruf des [[List|list-Kommandos]] einsehen.&lt;br /&gt;
&lt;br /&gt;
Es gibt bereits vorbelegte Internals welche in FHEM dazu dienen definitionsbezogene Informationen wie bspw. Namen und Readings zu speichern. Dies sind im besonderen:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;min-width: 13em;&amp;quot; | Internal !!  Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{NAME}&amp;lt;/code&amp;gt;  || Der Definitionsname, mit dem das Gerät angelegt wurde.  &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{READINGS}&amp;lt;/code&amp;gt;  || Enthält alle aktuell vorhandenen Readings. Daten unterhalb dieses Knotens sollte man nicht direkt manipulieren. Um Readings zu Erzeugen gibt es entsprechende [[DevelopmentModuleAPI#Readings_.2F_Events|Reading-Funktionen]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{NR}&amp;lt;/code&amp;gt;  || Die Positions-Nr. der Definition innerhalb der Konfiguration. Diese dient dazu die Konfiguration in der gleichen Reihenfolge zu speichern, wie die einzelnen Geräte angelegt wurden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{TYPE}&amp;lt;/code&amp;gt;  || Der Modulname, mit welchem die Definition angelegt wurde.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{DEF}&amp;lt;/code&amp;gt;  || Sämtliche Argumente, welche beim &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Befehl nach dem Modulnamen übergeben wurden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{CFGFN}&amp;lt;/code&amp;gt;  || Der Dateiname der Konfigurationsdatei in der diese Definition enthalten ist (sofern nicht in fhem.cfg). Dieser Wert ist nur gefüllt, wenn man mit mehreren Konfigurationsdateien arbeitet, welche dann in fhem.cfg via include-Befehl eingebunden werden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{NTFY_ORDER}&amp;lt;/code&amp;gt;  || Sofern das Modul Events via [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] verarbeitet enthält jede Definition eine Notify-Order als Zeichenkette bestehend aus dem Notify Order Prefix und dem Definitionsnamen. Details zur Funktionsweise gibt es in der Beschreibung zur [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] im Abschnitt &amp;quot;Reihenfolge für den Aufruf der Notify-Funktion beeinflussen&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt;  || Sofern das Modul Events via NotifyFn verarbeitet kann man damit die Definitionen, von denen man Events erhalten will begrenzen. Details zur Funktionsweise gibt es in der Beschreibung zur [[DevelopmentModuleIntro#X_Notify|Notify-Funktion]] im Abschnitt &amp;quot;Begrenzung der Aufrufe auf bestimmte Geräte&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt;  || Hier wird das zugeordnete IO-Gerät durch [[DevelopmentModuleAPI#AssignIoPort|AssignIoPort()]] gespeichert, welches für den Datentransport und -empfang dieses logischen Gerätes zuständig ist. Dieser Wert existiert nur bei Modulen die nach dem [[DevelopmentModuleIntro#Zweistufiges_Modell_f.C3.BCr_Module|zweistufigen Modulkonzept]] arbeiten. &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt;  || Hier werden alle Events kurzzeitig gesammelt, welche für die Eventverarbeitung anstehen. Insbesondere die [[DevelopmentModuleAPI#Readings_.2F_Events|Reading-Funktionen]] speichern hier alle Events zwischen um sie nach Abschluss via [[DevelopmentModuleAPI#DoTrigger|DoTrigger()]] zu verarbeiten. &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{FD}&amp;lt;/code&amp;gt;  || Wenn die Definition eine Netzwerkverbindung oder serielle Schnittstelle geöffnet hat (z.B. via [[DevIo]]), so wird der entsprechende File-Deskriptor in diesem Internal gespeichert. Damit kann FHEM alle geöffneten Filedeskriptoren der entsprechenden Definition zuordnen um bei ankommenden Daten die Definition via [[DevelopmentModuleIntro#X_Read|Read-Funktion]] damit zu versorgen.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash-&amp;gt;{EXCEPT_FD}&amp;lt;/code&amp;gt;  || Ähnlich wie &amp;lt;code&amp;gt;$hash-&amp;gt;{FD}&amp;lt;/code&amp;gt;. Sofern die Definition in &amp;lt;code&amp;gt;[[#Wichtige_globale_Variablen_aus_fhem.pl|%selectlist]]&amp;lt;/code&amp;gt; eingetragen ist und ein Fildeskriptor in diesem Internal gesetzt ist, wird bei einer auftretenden Exception bzw. Interrupt die [[DevelopmentModuleIntro#X_Except|Except]]-Funktion des entsprechenden Moduls aufgerufen um darauf zu reagieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Generell sollte man die meisten der hier genannten systemweiten Internals nicht modifizieren, da ansonsten die korrekte Funktionsweise von FHEM nicht mehr garantiert werden kann.&lt;br /&gt;
&lt;br /&gt;
== Readings ==&lt;br /&gt;
Daten, welche von einem Gerät gelesen werden und in FHEM in einer für Menschen verständlichen Form zur Verfügung gestellt werden können, werden Readings genannt. Sie geben den Status des Gerätes wieder und erzeugen Events innerhalb von FHEM auf die andere Geräte reagieren können. Sie werden als Unterstruktur des Hashes der jeweiligen Geräteinstanz gespeichert, beispielsweise &lt;br /&gt;
*&amp;lt;code&amp;gt;$hash-&amp;gt;{READINGS}{temperature}{VAL}&amp;lt;/code&amp;gt; für die Temperatur eines Fühlers&lt;br /&gt;
*&amp;lt;code&amp;gt;$hash-&amp;gt;{READINGS}{temperature}{TIME}&amp;lt;/code&amp;gt; für den Zeitstempel der Messung&lt;br /&gt;
&lt;br /&gt;
Für den lesenden Zugriff auf Readings steht die Funktion &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#ReadingsVal|ReadingsVal()]]&amp;lt;/code&amp;gt; zur Verfügung. Ein direkter Zugriff auf die Datenstruktur sollte nicht vorgenommen werden.&lt;br /&gt;
&lt;br /&gt;
Readings werden im Statefile von FHEM automatisch auf der Festplatte zwischengespeichert, damit sie nach einem Neustart sofort wieder zur Verfügung stehen. Dadurch ist der letzte Status eines Gerätes vor einem Neustart nachvollziehbar.&lt;br /&gt;
&lt;br /&gt;
Readings, die mit einem Punkt im Namen beginnen, haben eine funktionale Besonderheit. Sie werden im FHEMWEB nicht angezeigt und können somit als &amp;quot;Permanentspeicher&amp;quot; für kleinere Daten innerhalb des Moduls genutzt werden. Um größere Datenmengen permanent zu speichern sollte man jedoch die Funktion &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#setKeyValue|setKeyValue()]]&amp;lt;/code&amp;gt; verwenden.&lt;br /&gt;
&lt;br /&gt;
Zum Setzen von Readings sollen &lt;br /&gt;
*bei Gruppen von Readings der Funktionsblock &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#readingsBeginUpdate|readingsBeginUpdate()]]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#readingsBulkUpdate|readingsBulkUpdate()]]&amp;lt;/code&amp;gt; (mehrfach wiederholt), &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#readingsEndUpdate|readingsEndUpdate()]]&amp;lt;/code&amp;gt;&lt;br /&gt;
*bei einzelnen Updates die Funktion &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#readingsSingleUpdate|readingsSingleUpdate()]]&amp;lt;/code&amp;gt; &lt;br /&gt;
aufgerufen werden. Dabei kann man auch angeben, ob dabei ein Event ausgelöst werden soll oder nicht. Events erzeugen, je nach Hardwareperformance, spürbare Last auf dem System (siehe [[DevelopmentModuleIntro#X_Notify|NotifyFn]]), das Ändern von Readings ohne dass dabei Events erzeugt werden jedoch nicht.&lt;br /&gt;
&lt;br /&gt;
Eine Sequenz zum Setzen von Readings könnte folgendermaßen aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsBeginUpdate($hash);&lt;br /&gt;
readingsBulkUpdate($hash, $readingName1, $wert1 );&lt;br /&gt;
readingsBulkUpdate($hash, $readingName2, $wert2 );&lt;br /&gt;
readingsEndUpdate($hash, 1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um Readings zu löschen, wird für die Modulprogrammierung die Funktion &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#readingsDelete|readingsDelete()]]&amp;lt;/code&amp;gt; empfohlen. Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingsDelete($hash, $readingsname) &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{Hinweis|&#039;&#039;&#039;Hintergrundinfo dazu aus dem Forum:&#039;&#039;&#039; {{Link2Forum|Topic=83069|Message=753066}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CommandDeleteReading()&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;deletereading&amp;lt;/code&amp;gt; ist eher fuer den Endbenutzer und seine userReadings gedacht, und macht bei den Modulen die unnoetige Schleife ueber [[DevelopmentModuleAPI#devspec2array|devspec2array()]]. Wenn der Modulautor beim Aufruf auch &amp;lt;code&amp;gt;$cl&amp;lt;/code&amp;gt; weitergibt, und der Anwender meint, dieses Geraet auf blacklist setzen zu muessen, dann kann das Modul sein eigenes Reading nicht entfernen, und das ist kontraproduktiv.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Events ==&lt;br /&gt;
&lt;br /&gt;
FHEM verfügt über einen Event-Mechanismus um Änderungen verschiedenster Art an einzelne oder alle Definitionen mitzuteilen. Jedes Modul (und damit alle Definitionen dieses Moduls) können auf Events von FHEM selber (Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt;) oder von anderen Definitionen reagieren und dadurch selber aktiv werden. Ein Event wird innerhalb von FHEM als Zeichenkette behandelt.&lt;br /&gt;
&lt;br /&gt;
Events sind grundsätzlich immer definitionsbezogen. Das bedeutet, dass ein Event immer in Verbindung mit einem Definitionsnamen erzeugt wird. Jede Definition, welche ein Event verarbeitet, erhält den Definitions-Hash (&amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;) der auslösenden Definition.&lt;br /&gt;
&lt;br /&gt;
Events werden typischerweise bei der Erstellung von Readings implizit für jedes einzelne Reading erzeugt. Es gibt jedoch auch Events die nichts mit Readings zu tun haben um anderweitige Änderungen bekannt zu geben.&lt;br /&gt;
&lt;br /&gt;
Eigene Events können in FHEM mit der Funktion [[DevelopmentModuleAPI#DoTrigger|DoTrigger()]] erzeugt werden. Um auf Events in einem Modul reagieren zu können, muss eine [[#X_Notify|Notify]]-Funktion implementiert sein. Sobald ein oder mehrere Events für eine Definition getriggert werden, prüft FHEM, welche Definitionen über Events der auslösenden Definition informiert werden möchten. Diese werden dann nacheinander in einer bestimmten Reihenfolge durch Aufruf der [[#X_Notify|Notify]]-Funktion über anstehende Events in Kenntnis gesetzt. Es obliegt dann dem jeweiligen Modul, wie es auf die Events reagiert.&lt;br /&gt;
&lt;br /&gt;
=== globale Events ===&lt;br /&gt;
&lt;br /&gt;
Als &amp;quot;globale Events&amp;quot; werden alle Events bezeichnet, die durch die Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; erzeugt werden. Es handelt sich hierbei um Events die Strukturänderungen in der Konfiguration, als auch systemweite Ereignisse zu FHEM selbst signalisieren.&lt;br /&gt;
&lt;br /&gt;
Hier eine kurze Zusammenfassung, welche Events durch &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; getriggert werden können:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Allgemeine Events:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event-Text !! Beschreibung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;INITIALIZED&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Start von FHEM ist abgeschlossen. Sämtliche Definitionen und Attribute wurden aus der Konfiguration (fhem.cfg oder configDB) eingelesen, sowie sämtliche Readings sind aus dem State-File eingelesen und stehen nun voll umfänglich zur Verfügung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;REREADCFG&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Konfiguration wurde erneut eingelesen. Dies bedeutet, es wurden alle Definitionen/Attribute/Readings aus FHEM entfernt und durch Einlesen der Konfiguration neu angelegt. (FHEM-Befehl: &amp;quot;rereadcfg&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;SAVE&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die laufende Konfiguration soll gespeichert werden (in fhem.cfg oder configDB). Dieses Event wird &#039;&#039;&#039;VOR&#039;&#039;&#039; dem Speichern der Konfiguration getriggert. Sobald der Trigger verarbeitet wurde, beginnt das Speichern der Konfiguration. (FHEM-Befehl: &amp;quot;save&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;SHUTDOWN&amp;lt;/code&amp;gt;&#039;&#039;&#039; || FHEM wird sich beenden. (FHEM-Befehl: &amp;quot;shutdown&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt; DELAYEDSHUTDOWN &amp;lt;/code&amp;gt;&#039;&#039;&#039; || FHEM wird sich beenden. (FHEM-Befehl: &amp;quot;shutdown&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Es wurde ein Update erfolgreich installiert. (FHEM-Befehl: &amp;quot;update&amp;quot;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Definitionsbezogene Events:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event-Text !! Beschreibung.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;DEFINED &#039;&#039;&amp;lt;Name&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Es wurde eine neue Definition mit Namen &amp;lt;code&amp;gt;&#039;&#039;&amp;lt;Name&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt; angelegt. (FHEM-Befehl: &amp;quot;define&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;DELETED &#039;&#039;&amp;lt;Name&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Definition mit dem Namen &amp;lt;code&amp;gt;&#039;&#039;&amp;lt;Name&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt; wurde gelöscht. (FHEM-Befehl: &amp;quot;delete&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;RENAMED &#039;&#039;&amp;lt;Alt&amp;gt;&#039;&#039; &#039;&#039;&amp;lt;Neu&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Definition mit dem Namen &amp;lt;code&amp;gt;&#039;&#039;&amp;lt;Alt&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt; wurde in den Namen &amp;lt;code&amp;gt;&#039;&#039;&amp;lt;Neu&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt; umbenannt. (FHEM-Befehl: &amp;quot;rename&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;MODIFIED &#039;&#039;&amp;lt;Name&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die Definition mit dem Namen &amp;lt;code&amp;gt;&#039;&#039;&amp;lt;Name&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt; wurde modifiziert. (FHEM-Befehl: &amp;quot;modify&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;UNDEFINED &#039;&#039;&amp;lt;Name&amp;gt; &amp;lt;Modul&amp;gt; &amp;lt;Define-Parameter&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Es wurde eine Nachricht von einem physikalischen Modul (siehe [[#Zweistufiges Modell für Module|zweistufiges Modulkonzept]]) erhalten, für die keine passende logische Definition in FHEM existiert. Details dazu, siehe dazu Abschnitt [[#Automatisches Anlegen von logischen Gerätedefinitionen (autocreate)|Automatisches Anlegen von logischen Gerätedefinitionen (autocreate)]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Begrenzung von Events ===&lt;br /&gt;
&lt;br /&gt;
Ein Modul, welches Events verarbeitet, kann die Eventverarbeitung auf bestimmte Definitionen begrenzen. Dadurch werden nur Events an das Modul gemeldet (via [[#X_Notify|X_Notify()]]), welche von einer oder mehreren bestimmten Definitionen getriggert wurden. Dadurch werden unnötige Events nicht an das Modul gemeldet und schont somit Ressourcen.&lt;br /&gt;
&lt;br /&gt;
Standardmäßig werden sämtliche Events ohne Begrenzung an ein Modul gemeldet, welches eine [[#X_Notify|Notify]]-Funktion implementiert hat und somit Events verarbeiten kann. Details zur Begrenzung von Events findet man in der Beschreibung zur Modulfunktion [[#X_Notify|X_Notify()]].&lt;br /&gt;
&lt;br /&gt;
=== Reihenfolge der Eventverarbeitung ===&lt;br /&gt;
&lt;br /&gt;
Ein getriggertes Event wird nacheinander gegen jede Definition geprüft, deren Modul eine [[#X_Notify|Notify]]-Funktion implementiert hat. Dies bedeutet, jede Definition wird nacheinander durch Aufruf der [[#X_Notify|Notify]]-Funktion mit dem Definitionshash der auslösenden Definition aufgerufen.&lt;br /&gt;
&lt;br /&gt;
Unter bestimmten Umständen kann es erforderlich sein, in diese Reihenfolge einzugreifen. Beispielsweise wenn das eigene Modul und deren Definitionen das Event als letztes oder erstes verarbeiten müssen. Ein Beispiel bietet hierbei das Modul [[dewpoint]], welches Events vor allen anderen Modulen verarbeiten muss.&lt;br /&gt;
&lt;br /&gt;
Details, wie man die Reihenfolge der Eventverarbeitung steuern kann, findet man in der Beschreibung zur Modulfunktion [[#X_Notify|X_Notify()]].&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Damit der Nutzer das Verhalten einer einzelnen Gerätedefinition zur Laufzeit individuell anpassen kann, gibt es in FHEM für jede Definition sogenannte Attribute, welche mit dem Befehl &amp;lt;code&amp;gt;attr&amp;lt;/code&amp;gt; gesetzt werden können.&lt;br /&gt;
Diese stehen dann dem Modul unmittelbar zur Verfügung um das Verhalten während der Ausführung zu beeinflussen. Attribute werden zusammen mit dem &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Befehl der jeweiligen Definition beim Speichern der aktuellen Konfiguration von FHEM in die Konfigurationsdatei geschrieben. Beim Neustart werden die entsprechenden Befehle ausgeführt um alle Definition inkl. Attribute wieder anzulegen. Zur Laufzeit werden Attribute in dem globalen Hash &amp;lt;code&amp;gt;%attr&amp;lt;/code&amp;gt; mit dem Definitionsnamen als Index (&amp;lt;code&amp;gt;$attr{$name} = $value&amp;lt;/code&amp;gt;) gespeichert. Ein Attribut mit dem Namen &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt; würde beispielsweise mit &amp;lt;code&amp;gt;$attr{$name}{header}&amp;lt;/code&amp;gt; adressiert. Generell sollte &amp;lt;code&amp;gt;%attr&amp;lt;/code&amp;gt; nicht durch direkten Zugriff manipuliert/benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Zum Auslesen von Attributen sollte die Funktion [[DevelopmentModuleAPI#AttrVal|AttrVal()]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Welche Attribute ein Modul unterstützt muss in der Funktion &amp;lt;code&amp;gt;[[#X_Initialize|X_Initialize]]&amp;lt;/code&amp;gt; durch Setzen von &amp;lt;code&amp;gt;$hash-&amp;gt;{AttrList}&amp;lt;/code&amp;gt; bekannt gemacht werden (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Wenn beim Setzen von Attributen in einer Gerätedefinition entsprechende Werte geprüft werden sollen oder zusätzliche Funktionalitäten implementiert werden müssen, dann muss dies in der Funktion &amp;lt;code&amp;gt;[[#X_Attr|X_Attr]]&amp;lt;/code&amp;gt; (siehe unten) implementiert werden. Hier kann man bspw. einen Syntaxcheck für Attribut-Werte implementieren um ungültige Werte zurückzuweisen.&lt;br /&gt;
&lt;br /&gt;
== Modulfunktionen ==&lt;br /&gt;
&lt;br /&gt;
Damit fhem.pl ein Modul nutzen kann, muss dieses entsprechende Funktionen mit einer vorgegebenen Aufrufsyntax implementieren. Durch die Bekanntgabe dieser modulspezifischen Funktionen können Daten zwischen fhem.pl und einem Modul entsprechend ausgetauscht werden. Es gibt verschiedene Arten von Funktionen die ein Modul anbieten muss bzw. kann, je nach Funktionsumfang.&lt;br /&gt;
&lt;br /&gt;
=== Die wichtigsten Funktionen in einem Modul ===&lt;br /&gt;
&lt;br /&gt;
Folgende Funktion muss ein Modul mit dem beispielhaften Namen &amp;quot;X&amp;quot; mindestens bereitstellen:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left&amp;quot; | Funktionsname !! style=&amp;quot;text-align:left&amp;quot; | Kurzbeschreibung&lt;br /&gt;
|-&lt;br /&gt;
|  [[#X_Initialize|X_Initialize]] || Initialisiert das Modul und gibt den Namen zusätzlicher Modulfunktionen bekannt, sowie modulspezifische Einstellungen. Wird direkt nach dem erfolgreichen Laden des Moduls durch fhem.pl aufgerufen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen sind die wichtigsten Funktionen, welche je nach Anwendungsfall zu implementieren sind. Es handelt sich hierbei um die wichtigsten Vertreter, welche in den meisten Modulen Verwendung finden. Nicht alle Funktionen machen jedoch in jedem Modul Sinn. Generell sollte auch hier bei jeder Funktion der Modulname vorangestellt werden um ein einheitliches Namensschema zu gewährleisten. Hier die wichtigsten Modulfunktionen:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left&amp;quot; | Funktionsname !! style=&amp;quot;text-align:left&amp;quot; class=&amp;quot;unsortable&amp;quot; | Kurzbeschreibung&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Define|X_Define]] || Wird im Rahmen des &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Befehls aufgerufen.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Undef|X_Undef]] || Wird im Rahmen des &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt;-Befehls, sowie &amp;lt;code&amp;gt;rereadcfg&amp;lt;/code&amp;gt;-Befehl aufgerufen. Dient zum Abbau von offenen Verbindungen, Timern, etc.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Delete|X_Delete]] || Wird im Rahmen des beim &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt;-Befehls aufgerufen wenn das Gerät endgültig gelöscht wird um weiterführende Aktionen vor dem Löschen durchzuführen.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Get|X_Get]] || Wird im Rahmen des &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt;-Befehls aufgerufen um Daten vom Gerät abzufragen&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Set|X_Set]]  || Wird im Rahmen des &amp;lt;code&amp;gt;set&amp;lt;/code&amp;gt;-Befehls aufgerufen um Daten an das Gerät zu senden.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Attr|X_Attr]]  || Wird im Rahmen des &amp;lt;code&amp;gt;attr&amp;lt;/code&amp;gt;-Befehls aufgerufen um Attributwerte zu prüfen)&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Read|X_Read]]  || Wird durch FHEM aufgerufen, wenn ein gelisteter Filedeskriptor in &amp;lt;code&amp;gt;[[#Wichtige_globale_Variablen_aus_fhem.pl|%selectlist]]&amp;lt;/code&amp;gt; Daten zum Lesen bereitstellt.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Ready|X_Ready]]  || Wird unter Windows durch FHEM aufgerufen um zyklisch einen seriellen Filedeskriptor auf lesbare Daten zu prüfen. Unter Linux dient diese Funktion dem Wiederaufbau verlorener Verbindungen.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Notify|X_Notify]]  || Verarbeitet Events von anderen Geräten innerhalb von FHEM&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Rename|X_Rename]] || Wird aufgerufen, wenn ein Gerät umbenannt wird.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Shutdown|X_Shutdown]] || Wird beim Herunterfahren von FHEM ausgeführt.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_DelayedShutdown | X_DelayedShutdown]] || Wird beim Herunterfahren von FHEM ausgeführt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Diese Funktionen werden in diesem Abschnitt genauer beschrieben.&lt;br /&gt;
&lt;br /&gt;
==== X_Initialize ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Initialize($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
	...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; im Namen muss dabei auf den Namen des Moduls bzw. des definierten Gerätetyps geändert werden. Im Modul mit der Datei &amp;lt;code&amp;gt;36_JeeLink.pm&amp;lt;/code&amp;gt; beispielsweise ist der Name der Funktion &amp;lt;code&amp;gt;JeeLink_Initialize&amp;lt;/code&amp;gt;. Die Funktion wird von fhem.pl nach dem Laden des Moduls aufgerufen und bekommt eine leere Hashreferenz für den Initialisierungsvorgang übergeben. &lt;br /&gt;
&lt;br /&gt;
Dieser Hash muss nun von X_Initialize mit allen modulrelevanten Funktionsnamen gefüllt werden. Anschließend wird dieser Hash durch fhem.pl im globalen Hash &amp;lt;code&amp;gt;%modules&amp;lt;/code&amp;gt; gespeichert. &amp;lt;code&amp;gt;$modules{ModulName}&amp;lt;/code&amp;gt; wäre dabei der Hash für das Modul mit dem Namen &amp;lt;code&amp;gt;ModulName&amp;lt;/code&amp;gt;. Es handelt sich also nicht um den oben beschriebenen Hash der Geräteinstanzen sondern einen Hash, der für jedes Modul existiert und modulspezifische Daten wie bspw. die implementierten Modulfunktionen enthält. Die Initialize-Funktion setzt diese Funktionsnamen, in den Hash des Moduls wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$hash-&amp;gt;{DefFn}                = &amp;quot;X_Define&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{UndefFn}              = &amp;quot;X_Undef&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{DeleteFn}             = &amp;quot;X_Delete&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{SetFn}                = &amp;quot;X_Set&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{GetFn}                = &amp;quot;X_Get&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{AttrFn}               = &amp;quot;X_Attr&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{ReadFn}               = &amp;quot;X_Read&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{ReadyFn}              = &amp;quot;X_Ready&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{NotifyFn}             = &amp;quot;X_Notify&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{RenameFn}             = &amp;quot;X_Rename&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{ShutdownFn}           = &amp;quot;X_Shutdown&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{DelayedShutdownFn}    = &amp;quot;X_ DelayedShutdown&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um eine entsprechende Funktion in FHEM bekannt zu machen muss dazu der Funktionsname, wie er im Modul als &amp;lt;code&amp;gt;sub &amp;amp;lt;&#039;&#039;Funktionsname&#039;&#039;&amp;amp;gt;() { ... }&amp;lt;/code&amp;gt; definiert ist, als Zeichenkette in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; gesetzt werden. Dabei sollten die entsprechenden Funktionsnamen immer den Modulnamen (in diesem Beispiel &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt;) als Präfix verwenden.&lt;br /&gt;
Auf diese Weise können sämtliche modulspezifisch implementierten Funktionen wie &amp;lt;code&amp;gt;X_Read&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;X_Parse&amp;lt;/code&amp;gt; etc. durch Zuweisung an &amp;lt;code&amp;gt;$hash-&amp;gt;{ReadFn}&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;$hash-&amp;gt;{ParseFn}&amp;lt;/code&amp;gt; usw. bekannt gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus sollten die vom Modul unterstützten Attribute definiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$hash-&amp;gt;{AttrList} =&lt;br /&gt;
  &amp;quot;do_not_notify:1,0 &amp;quot; . &lt;br /&gt;
  &amp;quot;header &amp;quot; .&lt;br /&gt;
  $readingFnAttributes;  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Auflistung aller unterstützten modulspezifischen Attribute erfolgt in Form einer durch Leerzeichen getrennten Liste in &amp;lt;code&amp;gt;$hash-&amp;gt;{AttrList}&amp;lt;/code&amp;gt;. Es gibt in FHEM globale Attribute, die in allen Gerätedefinitionen verfügbar sind und nur modulspezifische Attribute die jedes Modul via &amp;lt;code&amp;gt;$hash-&amp;gt;{AttrList}&amp;lt;/code&amp;gt; über die eigene Initialize-Funktion setzt.  In fhem.pl werden dann die entsprechenden Attributwerte beim Aufruf eines &amp;lt;code&amp;gt;attr&amp;lt;/code&amp;gt;-Befehls in die globale Datenstruktur &amp;lt;code&amp;gt;$attr{$name}&amp;lt;/code&amp;gt;, z.B. &amp;lt;code&amp;gt;$attr{$name}{header}&amp;lt;/code&amp;gt; für das Attribut &amp;lt;code&amp;gt;header&amp;lt;/code&amp;gt; gespeichert. Falls im Modul weitere Aktionen oder Prüfungen beim Setzen eines Attributs nötig sind, dann kann wie im Beispiel oben die [[#X_Attr|Attr]]-Funktion implementiert und in der Initialize-Funktion bekannt gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;code&amp;gt;$readingFnAttributes&amp;lt;/code&amp;gt;, die im obigen Beispiel an die Liste der unterstützten Attribute angefügt wird, definiert Attributnamen, die dann zusätzlich gemacht werden, wenn das Modul zum Setzen von Readings die Funktionen &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#readingsBeginUpdate|readingsBeginUpdate()]]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#readingsBulkUpdate|readingsBulkUpdate()]]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#readingsEndUpdate|readingsEndUpdate()]]&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#readingsSingleUpdate|readingsSingleUpdate()]]&amp;lt;/code&amp;gt; verwendet. In diesen Funktionen werden Attribute wie &amp;lt;code&amp;gt;event-min-interval&amp;lt;/code&amp;gt; oder auch &amp;lt;code&amp;gt;event-on-change-reading&amp;lt;/code&amp;gt; ausgewertet. Für Details hierzu siehe commandref zu {{Link2CmdRef|Anker=readingFnAttributes|Label=readingFnAttributes}}.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Nutzung von parseParams()&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;code&amp;gt; [[DevelopmentModuleAPI#parseParams|parseParams()]]&amp;lt;/code&amp;gt; unterstützt Modul-Autoren beim Parsen von Übergabeparametern, welche bei &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;set&amp;lt;/code&amp;gt; Kommandos an die entsprechenden Modulfunktionen übergeben werden. Dadurch lassen sich auf einfache Weise insbesondere komplexe Parameter (wie bspw. Perl-Ausdrücke) sehr einfach parsen.&lt;br /&gt;
&lt;br /&gt;
Diese Zusatzfunktion kann man in der Initialize-Funktion einfach über folgenden Parameter für [[#X_Define|Define]]-, [[#X_Get|Get]]- und [[#X_Set|Set]]-Funktion modulweit aktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Sobald es gesetzt ist wird automatisch durch fhem.pl &amp;lt;code&amp;gt;[[DevelopmentModuleAPI#parseParams|parseParams()]]&amp;lt;/code&amp;gt; aufgerufen und die an die [[#X_Define|Define]]-, [[#X_Get|Get]]- und [[#X_Set|Set]]-Funktion übergebenen Parameter ändern sich wie weiter unten in den jeweiligen Funktionen beschrieben.&lt;br /&gt;
&lt;br /&gt;
==== X_Define ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Define($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $def ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
 &lt;br /&gt;
	return $error;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Define-Funktion eines Moduls wird von FHEM aufgerufen wenn der Define-Befehl für ein Geräte ausgeführt wird und das Modul bereits geladen und mit der Initialize-Funktion initialisiert ist. Sie ist typischerweise dazu da, die übergebenen Parameter zu prüfen und an geeigneter Stelle zu speichern sowie einen Kommunikationsweg zum Gerät zu öffnen (z.B. TCP-Verbindung, USB-Schnittstelle o.ä.) oder einen [[#Pollen_von_Geräten|Status-Timer]] zu starten.&lt;br /&gt;
Sie beginnt typischerweise mit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Define($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $def ) = @_;&lt;br /&gt;
	my @a = split( &amp;quot;[ \t][ \t]*&amp;quot;, $def );&lt;br /&gt;
	...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Übergabeparameter bekommt die Define-Funktion den Hash der Geräteinstanz sowie den die im &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Befehl übergebenen Parameter. Welche bzw. wie viele Parameter &lt;br /&gt;
akzeptiert werden und welcher Syntax diese entsprechen müssen ist Sache dieser Funktion. Im obigen Beispiel wird die Argumentzeile &amp;lt;code&amp;gt;$def&amp;lt;/code&amp;gt; in ein Array aufgeteilt (durch Leerzeichen/Tabulator getrennt) und so können die vom Modul bzw. der Define-Funktion erwarteten Werte über das Array der Reihe nach verarbeitet werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
my $name   = $a[0];&lt;br /&gt;
my $module = $a[1];&lt;br /&gt;
my $url    = $a[2];&lt;br /&gt;
my $inter  = 300;&lt;br /&gt;
&lt;br /&gt;
if(int(@a) == 4) { &lt;br /&gt;
	$inter = $a[3]; &lt;br /&gt;
	if ($inter &amp;lt; 5) {&lt;br /&gt;
		return &amp;quot;interval too small, please use something &amp;gt; 5s, default is 300 seconds&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit die übergebenen Werte auch anderen Funktionen zur Verfügung stehen und an die jeweilige Geräteinstanz gebunden sind, werden die Werte typischerweise als Internals im Hash der Geräteinstanz gespeichert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$hash-&amp;gt;{url} 		= $url;&lt;br /&gt;
$hash-&amp;gt;{Interval}	= $inter;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sobald alle Parameter korrekt verarbeitet wurden, wird in der Regel die erste Verbindung zum Gerät aufgebaut. Je nach Art des Geräts kann das eine permanente Datenverbindung sein (z.B. serielle Schnittstelle oder TCP-Verbindung) oder das Starten eines regelmäßigen Timers, der zyklisch den Status z.B. via [[HttpUtils|HTTP]] ausliest.&lt;br /&gt;
&lt;br /&gt;
Sollten im Rahmen der Define-Funktion Syntax-Probleme der Übergabeparameter festgestellt werden oder es kann bspw. keine Verbindung aufgebaut werden, so ist als Funktionsrückgabewert eine entsprechende Fehlermeldung zurückzugeben. Nur wenn alle Übergabeparameter akzeptiert werden, darf &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben werden. Sobald eine Define-Funktion eine Fehlermeldung zurückmeldet, wird der define-Befehl durch FHEM zurückgewiesen und der User erhält die Fehlermeldung, welche die Define-Funktion produziert hat, als Ausgabe zurück.&lt;br /&gt;
&lt;br /&gt;
===== &amp;lt;u&amp;gt;Verfügbarkeit von Attributen&amp;lt;/u&amp;gt; =====&lt;br /&gt;
Während die Define-Funktion ausgeführt wird, sollte man nicht davon ausgehen, dass alle vom Nutzer konfigurierten Attribute via [[DevelopmentModuleAPI#AttrVal|AttrVal()]] verfügbar sind. Attribute stehen in der Define-Funktion nur dann zur Verfügung, wenn FHEM sich nicht in der Initialisierungsphase befindet (globale Variable &amp;lt;code&amp;gt;$init_done&amp;lt;/code&amp;gt; ist wahr; der Nutzer hat die Gerätedefinition modifiziert). Daher sollte man weiterführende Funktion, welche auf gesetzte Attribute angewiesen sind, nur dann in der Define-Funktion starten, wenn &amp;lt;code&amp;gt;$init_done&amp;lt;/code&amp;gt; zutrifft.&lt;br /&gt;
&lt;br /&gt;
Andernfalls sollte man den Aufruf in der Notify-Funktion durchführen sobald &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt; getriggert wurde:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Define($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $def ) = @_;&lt;br /&gt;
 &lt;br /&gt;
	...&lt;br /&gt;
&lt;br /&gt;
	$hash-&amp;gt;{NOTIFYDEV} = &amp;quot;global&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	X_FunctionWhoNeedsAttr($hash) if($init_done);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub X_Notify($$)&lt;br /&gt;
{&lt;br /&gt;
	my ($own_hash, $dev_hash) = @_;&lt;br /&gt;
	my $ownName = $own_hash-&amp;gt;{NAME}; # own name / hash&lt;br /&gt;
 &lt;br /&gt;
	return &amp;quot;&amp;quot; if(IsDisabled($ownName)); # Return without any further action if the module is disabled&lt;br /&gt;
 &lt;br /&gt;
	my $devName = $dev_hash-&amp;gt;{NAME}; # Device that created the events&lt;br /&gt;
	my $events = deviceEvents($dev_hash, 1);&lt;br /&gt;
&lt;br /&gt;
	if($devName eq &amp;quot;global&amp;quot; &amp;amp;&amp;amp; grep(m/^INITIALIZED|REREADCFG$/, @{$events}))&lt;br /&gt;
	{&lt;br /&gt;
		 X_FunctionWhoNeedsAttr($hash);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird die Modulfunktion X_FunctionWhoNeedsAttr() nach dem Start erst aufgerufen, wenn alle Attribute aus der Konfiguration geladen wurden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Nutzung von parseParams()&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Aufteilen und Parsen von &amp;lt;code&amp;gt;$def&amp;lt;/code&amp;gt; lässt sich die Funktion [[DevelopmentModuleAPI#parseParams|parseParams()]] verwenden um die einzelnen Argumente einfach zu parsen. Wenn in [[#X_Initialize|X_Initialize()]] &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; gesetzt wurde dann wird parseParams() automatisch aufgerufen und X_Define() ändert sich wie folgt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Define($$$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $a, $h ) = @_;&lt;br /&gt;
	...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die genauen Möglichkeiten von parseParams() sind in dem entsprechenden [[DevelopmentModuleAPI#parseParams|Artikel]] dokumentiert.&lt;br /&gt;
&lt;br /&gt;
==== X_Undef ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Undef ($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $name ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
 &lt;br /&gt;
	return $error;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Undef-Funktion wird aufgerufen wenn ein Gerät mit &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; gelöscht wird oder bei der Abarbeitung des Befehls &amp;lt;code&amp;gt;rereadcfg&amp;lt;/code&amp;gt;, der ebenfalls alle Geräte löscht und danach das Konfigurationsfile neu einliest. Entsprechend müssen in der Funktion typische Aufräumarbeiten durchgeführt werden wie das saubere Schließen von Verbindungen oder das Entfernen von internen Timern, sofern diese im Modul zum Pollen verwendet wurden (siehe Abschnitt [[#Pollen_von_Geräten|Pollen von Geräten]]). &lt;br /&gt;
&lt;br /&gt;
Zugewiesene Variablen im Hash der Geräteinstanz, Internals oder Readings müssen hier nicht gelöscht werden. In fhem.pl werden die entsprechenden Strukturen beim Löschen der Geräteinstanz ohnehin vollständig gelöscht.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Undef($$)    &lt;br /&gt;
{                     &lt;br /&gt;
	my ( $hash, $name) = @_;       &lt;br /&gt;
	DevIo_CloseDev($hash);         &lt;br /&gt;
	RemoveInternalTimer($hash);    &lt;br /&gt;
	return undef;                  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollten im Rahmen der Undef-Funktion Probleme festgestellt werden, die ein Löschen nicht zulassen, so ist als Funktionsrückgabewert eine entsprechende Fehlermeldung zurückzugeben. Nur wenn die Undef-Funktion erfolgreich durchgeführt wurde, darf &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben werden. Nur dann wird eine Gerätedefinition von FHEM auch tatsächlich gelöscht bzw. neu angelegt. Sollte die Undef-Funktion jedoch eine Fehlermeldung zurückgeben, wird der entsprechende Vorgang (&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;rereadcfg&amp;lt;/code&amp;gt;) für dieses Gerät abgebrochen. Es bleibt dann unverändert in FHEM bestehen.&lt;br /&gt;
&lt;br /&gt;
==== X_Delete ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Delete ($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $name ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
 &lt;br /&gt;
	return $error;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Delete-Funktion ist das Gegenstück zur Funktion [[#X_Define|X_Define]] und wird aufgerufen wenn ein Gerät mit dem Befehl &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; gelöscht wird. &lt;br /&gt;
&lt;br /&gt;
Wenn ein Gerät in FHEM gelöscht wird, wird zuerst die Funktion [[#X_Undef|X_Undef]] aufgerufen um offene Verbindungen zu schließen, anschließend wird die Funktion X_Delete aufgerufen. Diese dient eher zum Aufräumen von dauerhaften Daten, welche durch das Modul evtl. für dieses Gerät spezifisch erstellt worden sind. Es geht hier also eher darum, alle Spuren sowohl im laufenden FHEM-Prozess, als auch dauerhafte Daten bspw. im physikalischen Gerät zu löschen die mit dieser Gerätedefinition zu tun haben.&lt;br /&gt;
&lt;br /&gt;
Dies kann z.B. folgendes sein:&lt;br /&gt;
&lt;br /&gt;
* Löschen von Dateien im Dateisystem die während der Nutzung dieses Geräts angelegt worden sind.&lt;br /&gt;
* Lösen von evtl. Pairings mit dem physikalischen Gerät &lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Delete($$)    &lt;br /&gt;
{                     &lt;br /&gt;
	my ( $hash, $name ) = @_;       &lt;br /&gt;
&lt;br /&gt;
	# Löschen von Geräte-assoziiertem Temp-File&lt;br /&gt;
	unlink($attr{global}{modpath}.&amp;quot;/FHEM/FhemUtils/$name.tmp&amp;quot;;)&lt;br /&gt;
&lt;br /&gt;
	return undef;&lt;br /&gt;
}    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollten im Rahmen der Delete-Funktion Probleme festgestellt werden, die ein Löschen nicht zulassen, so ist als Funktionsrückgabewert eine entsprechende Fehlermeldung zurückzugeben. Nur die Delete-Funktion erfolgreich durchgeführt wurde, darf &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben werden. Nur dann wird eine Gerätedefinition von FHEM auch tatsächlich gelöscht. Sollte die Delete-Funktion eine Fehlermeldung zurückgeben, wird der Löschvorgang abgebrochen und das Gerät bleibt weiter in FHEM bestehen.&lt;br /&gt;
&lt;br /&gt;
==== X_Get ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Get ($$@)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $name, $opt, @args ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
 &lt;br /&gt;
	return $result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Get-Funktion wird aufgerufen wenn der FHEM-Befehl &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; für eine Definition dieses Moduls ausgeführt wird. Mit &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; werden typischerweise Werte von einem Gerät abgefragt. In vielen Modulen wird auf diese Weise auch der Zugriff auf generierte Readings ermöglicht. Der Get-Funktion wird dabei der Definitions-Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;, der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;, sowie die Aufrufparameter &amp;lt;code&amp;gt;$opt&amp;lt;/code&amp;gt; plus optional weiterer Parameter &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; übergeben. Als Rückgabewert &amp;lt;code&amp;gt;$result&amp;lt;/code&amp;gt; wird das Ergebnis des entsprechenden Befehls in Form einer Zeichenkette zurückgegeben. Der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; hat hierbei keine besondere Bedeutung und wird behandelt wie eine leere Zeichenkette &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Get($$@)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $name, $opt, @args ) = @_;&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;\&amp;quot;get $name\&amp;quot; needs at least one argument&amp;quot; unless(defined($opt));&lt;br /&gt;
&lt;br /&gt;
	if($opt eq &amp;quot;status&amp;quot;) &lt;br /&gt;
	{&lt;br /&gt;
	   ...&lt;br /&gt;
	}&lt;br /&gt;
	elsif($opt eq &amp;quot;power&amp;quot;)&lt;br /&gt;
	{&lt;br /&gt;
	   ...&lt;br /&gt;
	}&lt;br /&gt;
	...&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		return &amp;quot;Unknown argument $opt, choose one of status power [...]&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn eine unbekannte Option an die Get-Funktion übergeben wird, so muss als Rückgabewert der Funktion eine bestimmte Syntax eingehalten werden um FHEM mitzuteilen, welche Optionen für einen Get-Befehl aktuell unterstützt werden. Dies gilt insbesondere für den Aufruf &amp;lt;code&amp;gt;get &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;&amp;lt;NAME&amp;gt;&#039;&#039;&amp;lt;/font&amp;gt; &amp;lt;u&amp;gt;&#039;&#039;&#039;?&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt;, welche durch verschiedene Module (z.B. FHEMWEB) benutzt wird, um eine Liste aller unterstützten Befehle für eine Definition zu ermitteln. Die Rückgabe muss dabei folgender Syntax entsprechen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&#039;&#039;&#039;unknown&#039;&#039;&#039; argument &#039;&#039;&amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;[Parameter]&amp;lt;/font&amp;gt;&#039;&#039; &#039;&#039;&#039;choose one of&#039;&#039;&#039; &#039;&#039;&amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;[Liste möglicher Optionen]&amp;lt;/font&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei sind die fett gedruckten Teile der Rückmeldung besonders wichtig. Sind diese nicht vorhanden, können Module wie FHEMWEB nicht die möglichen Get-Kommandos für das entsprechende Gerät ermitteln. Es muss am Anfang der Meldung das Stichwort &amp;quot;unknown&amp;quot; vorkommen gefolgt von einer frei definierbaren Fehlermeldung (i.d.R der übergebene Parameter, welcher ungültig ist). Anschließend folgt &amp;quot;choose one of&amp;quot; mit einer anschließenden Liste möglicher Optionen getrennt durch ein Leerzeichen. &lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;return &amp;quot;unknown argument $opt choose one of status temperature humidity&amp;quot;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier werden als mögliche Optionen für einen Get-Befehl folgende Parameter angegeben:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;temperature&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;humidity&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies würde in folgenden, mögliche Get-Befehle für einen User resultieren:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;get &#039;&#039;&amp;amp;lt;NAME&amp;amp;gt;&#039;&#039; status&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;get &#039;&#039;&amp;amp;lt;NAME&amp;amp;gt;&#039;&#039; temperature&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;get &#039;&#039;&amp;amp;lt;NAME&amp;amp;gt;&#039;&#039; humidity&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im weiteren Verlauf der Get-Funktion könnte man dann mit dem physischen Gerät kommunizieren und den gefragten Wert direkt abfragen und diesen als Return-Wert der Get-Funktion zurückgeben. Vielfach werden aber auch die vorhandenen Readings zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Nutzung von parseParams()&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn in [[#X_Initialize|X_Initialize()]] &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; gesetzt wurde dann wird [[DevelopmentModuleAPI#parseParams|parseParams()]] automatisch aufgerufen und X_Get() ändert sich wie folgt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Get($$$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $a, $h ) = @_;&lt;br /&gt;
	...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die genauen Möglichkeiten von parseParams() sind in dem entsprechenden [[DevelopmentModuleAPI#parseParams|Artikel]] dokumentiert.&lt;br /&gt;
&lt;br /&gt;
==== X_Set ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Set ($$@)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $name, $cmd, @args ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
&lt;br /&gt;
	return $error;&lt;br /&gt;
	return ($error, $skip_trigger);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Set-Funktion ist das Gegenteil zur [[#X_Get|Get]]-Funktion. Sie ist dafür gedacht, Daten zum physischen Gerät zu schicken, bzw. entsprechende Aktionen im Gerät selber auszulösen. Ein Set-Befehl dient daher der direkten Steuerung des physikalischen Gerätes in dem es bspw. Zustände verändert (wie &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;). Der Set-Funktion wird dabei der Definitions-Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;, der Definitionsname &amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;, sowie die Aufrufparameter &amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; und optional weitere Argumente &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt; übergeben. Als Rückgabewert &amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; kann eine Fehlermeldung in Form Zeichenkette zurückgegeben werden. Der Rückgabewert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; bedeutet hierbei, dass der Set-Befehl erfolgreich durchgeführt wurde. Eine Set-Funktion gibt daher nur im Fehlerfall eine Rückmeldung mit einer entsprechenden Fehlermeldung. Der Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; wird als &amp;quot;erfolgreich&amp;quot; interpretiert. &lt;br /&gt;
&lt;br /&gt;
Standardmäßig wird jeder Set-Befehl, welcher erfolgreich ausgeführt wurde (&amp;lt;code&amp;gt;$error&amp;lt;/code&amp;gt; ist &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;), als Event getriggert um dies bspw. in einem FileLog festzuhalten. Dieses Verhalten kann optional unterbunden werden indem der optionale zweite Rückgabewert &amp;lt;code&amp;gt;$skip_trigger&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; gesetzt wird. Damit wird das Generieren eines Events für das erfolgreich ausgeführte Set-Kommando unterbunden. Falls nicht gesetzt, wird ein Event erzeugt (&amp;lt;code&amp;gt;$cmd&amp;lt;/code&amp;gt; mit sämtlichen &amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Rückmeldungen (Fehler) von set-Befehlen sämtlicher Module, die im Rahmen der Ausführung eines getriggerten [[Notify]] auftreten, werden im FHEM Logfile festgehalten.&lt;br /&gt;
&lt;br /&gt;
Falls nur interne Daten, die ausschließlich für das Modul relevant sind, gesetzt werden müssen, so sollte statt Set die [[#X_Attr|Attr]]-Funktion verwendet werden. Attribute werden bei Save-Config auch in der Fhem.cfg gesichert. Set-Befehle nicht, da sie nur zu Steuerungszwecken im laufenden Betrieb von FHEM dienen.&lt;br /&gt;
 &lt;br /&gt;
Eine Set-Funktion ist ähnlich aufgebaut wie die Get-Funktion, sie bekommt jedoch in der Regel weitere zusätzliche Parameter (&amp;lt;code&amp;gt;@args&amp;lt;/code&amp;gt;) übergeben um Zustände zu setzen/ändern. &lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Set($@)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $name, $cmd, @args ) = @_;&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;\&amp;quot;set $name\&amp;quot; needs at least one argument&amp;quot; unless(defined($cmd));&lt;br /&gt;
&lt;br /&gt;
	if($cmd eq &amp;quot;status&amp;quot;)&lt;br /&gt;
	{&lt;br /&gt;
	   if($args[0] eq &amp;quot;up&amp;quot;)&lt;br /&gt;
	   {&lt;br /&gt;
	      ...&lt;br /&gt;
	   }&lt;br /&gt;
	   elsif($args[0] eq &amp;quot;down&amp;quot;)&lt;br /&gt;
	   {&lt;br /&gt;
	      ...&lt;br /&gt;
	   }&lt;br /&gt;
	   else&lt;br /&gt;
	   {&lt;br /&gt;
	      return &amp;quot;Unknown value $args[0] for $cmd, choose one of status power&amp;quot;;&lt;br /&gt;
	   }   &lt;br /&gt;
	}&lt;br /&gt;
	elsif($cmd eq &amp;quot;power&amp;quot;)&lt;br /&gt;
	{&lt;br /&gt;
	   if($args[0] eq &amp;quot;on&amp;quot;)&lt;br /&gt;
	   {&lt;br /&gt;
	      ...&lt;br /&gt;
	   }&lt;br /&gt;
	   elsif($args[0] eq &amp;quot;off&amp;quot;)&lt;br /&gt;
	   {&lt;br /&gt;
	      ...&lt;br /&gt;
	   }  &lt;br /&gt;
	   else&lt;br /&gt;
	   {&lt;br /&gt;
	      return &amp;quot;Unknown value $args[0] for $cmd, choose one of status power&amp;quot;;&lt;br /&gt;
	   }       &lt;br /&gt;
	}&lt;br /&gt;
	...&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		return &amp;quot;Unknown argument $cmd, choose one of status power&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn eine unbekannte Option an die Set-Funktion übergeben wird, so muss als Rückgabewert der Funktion eine bestimmte Syntax eingehalten werden um FHEM mitzuteilen, welche Optionen für einen Set-Befehl aktuell unterstützt werden. Dies gilt insbesondere für den Aufruf &amp;lt;code&amp;gt;set &amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;&#039;&#039;&amp;lt;NAME&amp;gt;&#039;&#039;&amp;lt;/font&amp;gt; &amp;lt;u&amp;gt;&#039;&#039;&#039;?&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt;, welcher durch verschiedene Module (z.B. FHEMWEB) benutzt wird, um eine Liste aller unterstützten Befehle für eine Definition zu ermitteln. Die Rückgabe muss dabei folgender Syntax entsprechen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&#039;&#039;&#039;unknown&#039;&#039;&#039; argument &#039;&#039;&amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;[Parameter]&amp;lt;/font&amp;gt;&#039;&#039; &#039;&#039;&#039;choose one of&#039;&#039;&#039; &#039;&#039;&amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;[Liste möglicher Optionen]&amp;lt;/font&amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei sind die fett gedruckten Teile der Rückmeldung besonders wichtig. Sind diese nicht vorhanden, können Module wie FHEMWEB nicht die möglichen Set-Kommandos für das entsprechende Gerät ermitteln. Es muss am Anfang der Meldung das Stichwort &amp;quot;unknown&amp;quot; vorkommen gefolgt von einer frei definierbaren Fehlermeldung (i.d.R der übergebene Parameter, welcher ungültig ist). Anschließend folgt &amp;quot;choose one of&amp;quot; mit einer anschließenden Liste möglicher Optionen getrennt durch ein Leerzeichen. &lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;return &amp;quot;unknown argument $cmd choose one of status power&amp;quot;;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier werden als mögliche Optionen für einen Set-Befehl folgende Parameter angegeben:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;power&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies würde in folgenden, mögliche Set-Befehle für einen User resultieren:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;set &#039;&#039;&amp;amp;lt;NAME&amp;amp;gt;&#039;&#039; status&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;set &#039;&#039;&amp;amp;lt;NAME&amp;amp;gt;&#039;&#039; power&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Nutzung von SetExtensions.pm&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man dem Nutzer zusätzlich zu den Set-Befehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; auch weiterführende Befehle wie &amp;lt;code&amp;gt;on-for-timer&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;on-till&amp;lt;/code&amp;gt;, usw. anbieten möchte, obwohl die zu steuernde Hardware solche Kommandos nicht unterstützt, kann man dies über das Hilfsmodul SetExtensions.pm realisieren.&lt;br /&gt;
&lt;br /&gt;
Das Hilfsmodul SetExtensions.pm bietet weiterführende Set-Kommandos basierend auf den Befehlen &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; an. Dabei werden durch interne Timer bzw. eigens angelegten [[at]]-Definitionen diese Befehle durch FHEM selber umgesetzt. Je nach ausgeführtem Befehl wird der &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;- bzw. &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;-Befehl dann durch FHEM zum richtigen Zeitpunkt ausgeführt. Vorausgesetzt das Modul unterstützt in der Set-Funktion die Befehle &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;, so werden durch den Einsatz von SetExtensions.pm folgende Befehle zusätzlich unterstützt:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Set-Kommando !! Beispiel !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;on-for-timer &#039;&#039;&amp;amp;lt;Dauer&amp;amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;  || style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;on-for-timer 120&amp;lt;/code&amp;gt; || Schaltet das Gerät sofort mit dem &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;-Befehl ein und nach der angegebenen Dauer in Sekunden via &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; wieder aus.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;off-for-timer &#039;&#039;&amp;amp;lt;Dauer&amp;amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;  || style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;off-for-timer 120&amp;lt;/code&amp;gt; || Schaltet das Gerät sofort mit dem &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;-Befehl aus und nach der angegebenen Dauer in Sekunden via &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; wieder ein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;on-till &#039;&#039;&amp;amp;lt;Zeitpunkt&amp;amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;  || style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;on-till 16:30&amp;lt;/code&amp;gt; || Schaltet das Gerät sofort mit dem &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;-Befehl ein und zum angegebenen Zeitpunkt via &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; wieder aus.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;off-till &#039;&#039;&amp;amp;lt;Zeitpunkt&amp;amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;  || style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;off-till 16:30&amp;lt;/code&amp;gt; || Schaltet das Gerät sofort mit dem &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;-Befehl aus und zum angegebenen Zeitpunkt via &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; wieder ein.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;on-till-overnight &#039;&#039;&amp;amp;lt;Zeitpunkt&amp;amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;  || style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;on-till-overnight 01:00&amp;lt;/code&amp;gt; || Ähnlich wie &amp;lt;code&amp;gt;on-till&amp;lt;/code&amp;gt;. Der übergebene Zeitpunkt wird aber nicht geprüft, ob er für den heutigen Tag bereits überschritten wurde. Dadurch kann man Abends einen Zeitpunkt setzen, der erst am nächsten Tag zutrifft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;off-till-overnight &#039;&#039;&amp;amp;lt;Zeitpunkt&amp;amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;  || style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;off-till-overnight 01:00&amp;lt;/code&amp;gt; || Ähnlich wie &amp;lt;code&amp;gt;off-till&amp;lt;/code&amp;gt;. Der übergebene Zeitpunkt wird aber nicht geprüft, ob er für den heutigen Tag bereits überschritten wurde. Dadurch kann man Abends einen Zeitpunkt setzen, der erst am nächsten Tag zutrifft.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;blink &#039;&#039;&amp;amp;lt;Anzahl&amp;amp;gt; &amp;amp;lt;Interval&amp;amp;gt;&#039;&#039;&amp;lt;/code&amp;gt;  || style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;blink 3 1&amp;lt;/code&amp;gt; || Schaltet das Gerät via &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; für &amp;lt;code&amp;gt;&#039;&#039;&amp;amp;lt;Interval&amp;amp;gt;&#039;&#039;&amp;lt;/code&amp;gt; Sekunden ein und anschließend via &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; wieder aus. Nach &amp;lt;code&amp;gt;&#039;&#039;&amp;amp;lt;Interval&amp;amp;gt;&#039;&#039;&amp;lt;/code&amp;gt; Sekunden wird das ganze wiederholt, solange bis die angegebene Anzahl erreicht ist.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;intervals &#039;&#039;&amp;amp;lt;Start&amp;amp;gt;-&amp;amp;lt;Ende&amp;amp;gt;&#039;&#039; &#039;&#039;&amp;amp;lt;Start&amp;amp;gt;-&amp;amp;lt;Ende&amp;amp;gt;&#039;&#039; ...&amp;lt;/code&amp;gt; || style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;intervals 07:00-08:00 16:30-18:00&amp;lt;/code&amp;gt; || Schaltet das Gerät innerhalb der übergebenen Zeiträumen via &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; ein. Sobald die aktuelle Zeit ausserhalb dieser Zeiträume liegt, wird das Gerät via &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; wieder ausgeschaltet. Es können dabei beliebig viele Zeiträume angegeben werden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;toggle&amp;lt;/code&amp;gt; || style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;toggle&amp;lt;/code&amp;gt;  || Sofern der aktuelle Status &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; ist, wird das Gerät via &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt; ausgeschaltet. Andernfalls wird es via &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; eingeschaltet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Eine kurze Beschreibung zu den möglichen Befehlen durch SetExtensions.pm gibt es auch in der commandref zum {{Link2CmdRef|Anker=set|Label=set-Befehl}}.&lt;br /&gt;
&lt;br /&gt;
Um SetExtensions.pm in der Set-Funktion nutzen zu können müssen folgende Aktionen durchgeführt werden:&lt;br /&gt;
&lt;br /&gt;
# Laden von SetExtensions.pm via &amp;lt;code&amp;gt;use SetExtensions;&amp;lt;/code&amp;gt; am Anfang des Moduls&lt;br /&gt;
# Aufruf und Rückgabe der Funktion [[DevelopmentModuleAPI#SetExtensions|SetExtensions()]] sofern die Set-Funktion mit dem übergebenen Befehl nichts anfangen kann.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
use SetExtensions;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
sub X_Set($@)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $name, $cmd, @args ) = @_;&lt;br /&gt;
	my $cmdList = &amp;quot;on off&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;\&amp;quot;set $name\&amp;quot; needs at least one argument&amp;quot; unless(defined($cmd));&lt;br /&gt;
&lt;br /&gt;
	if($cmd eq &amp;quot;on&amp;quot;)&lt;br /&gt;
	{&lt;br /&gt;
		# Gerät einschalten...&lt;br /&gt;
	}&lt;br /&gt;
	elsif($cmd eq &amp;quot;off&amp;quot;)&lt;br /&gt;
	{&lt;br /&gt;
		# Gerät ausschalten...&lt;br /&gt;
	}&lt;br /&gt;
	...&lt;br /&gt;
	else # wenn der übergebene Befehl nicht durch X_Set() verarbeitet werden kann, Weitergabe an SetExtensions()&lt;br /&gt;
	{&lt;br /&gt;
		return SetExtensions($hash, $cmdList, $name, $cmd, @args);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sollte der übergebene Set-Befehl auch für SetExtensions unbekannt sein (bspw. &amp;lt;code&amp;gt;set &#039;&#039;&amp;amp;lt;Name&amp;amp;gt;&#039;&#039; ?&amp;lt;/code&amp;gt;), so generiert SetExtensions() eine entsprechende Usage-Meldung, welche innerhalb der Set-Funktion an FHEM zurückgegeben werden muss.&lt;br /&gt;
&lt;br /&gt;
Eine ausführliche Beschreibung zu der Funktion SetExtensions() gibt es in der  [[DevelopmentModuleAPI#SetExtensions|API-Referenz]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Nutzung von parseParams()&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn in [[#X_Initialize|X_Initialize()]] &amp;lt;code&amp;gt;$hash-&amp;gt;{parseParams} = 1;&amp;lt;/code&amp;gt; gesetzt wurde dann wird [[DevelopmentModuleAPI#parseParams|parseParams()]] automatisch aufgerufen und X_Set() ändert sich wie folgt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Set($$$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $a, $h ) = @_;&lt;br /&gt;
	...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die genauen Möglichkeiten von parseParams() sind in dem entsprechenden [[DevelopmentModuleAPI#parseParams|Artikel]] dokumentiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Nutzung von FHEMWEB-Widgets&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das GUI-Modul [[FHEMWEB]] kann für die einzelnen Set-Optionen, die das Modul versteht, automatisch Eingabehilfen wie Drop-Down Boxen oder Slider erzeugen. In der Detailansicht der GUI kann der Anwender dann die jeweiligen Werte komfortabel auswählen. Dafür muss die Set-Funktion, wenn sie mit der Option &amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt; aufgerufen wird, nicht nur einen Text mit  &amp;lt;code&amp;gt;&amp;quot;Unknown ... choose one of ...&amp;quot;&amp;lt;/code&amp;gt; zurückgeben sondern den einzelnen Set-Optionen in diesem Rückgabetext nach einem Doppelpunkt entsprechende Zusatzinformationen anhängen.&lt;br /&gt;
Meist prüft man in den Modulen gar nicht auf die Option &amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt; sondern gibt generell bei unbekannten Optionen diesen Text zurück. Das Modul FHEMWEB ermittelt die Syntax eines Gerätes jedoch immer mit dem Befehl:&lt;br /&gt;
 set &#039;&#039;&amp;amp;lt;NAME&amp;amp;gt;&#039;&#039; ?&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
	return &amp;quot;Unknown argument $cmd, choose one of status:up,down power:on,off on:noArg off:noArg&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit Kommata getrennte Werte ergeben eine Drop-Down Liste, mit der der User die Werte auswählen kann&lt;br /&gt;
&amp;lt;pre&amp;gt;timer:30,120,300&lt;br /&gt;
mode:verbose,ultra,relaxed&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wird kein Doppelpunkt zum Kommando angegeben, so wird eine Eingabezeile angezeigt, die die freie Eingabe eines Wertes erlaubt.&lt;br /&gt;
&lt;br /&gt;
Man kann jedoch die Eingabe-/Auswahlmöglichkeiten durch Widgets vereinfachen. Dazu gibt man hinter dem Doppelpunkt einen Widgetnamen und widgetspezifische Parameter an. Es existieren mehrere solcher Widgets in FHEMWEB. Die gebräuchlichsten sind:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Zusatz !! Beispiel !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;noArg&#039;&#039;&#039; || &amp;lt;code&amp;gt;reset:noArg&amp;lt;/code&amp;gt;|| Es werden keine weiteren Argumente mehr benötigt. In so einem Fall wird bei der Auswahl keine Textbox oder ähnliches angezeigt, da keine weiteren Argumente für diesen Befehl notwendig sind.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;slider&#039;&#039;&#039;,&amp;lt;min&amp;gt;,&amp;lt;step&amp;gt;,&amp;lt;max&amp;gt; || &amp;lt;code&amp;gt;dim:slider,0,1,100&amp;lt;/code&amp;gt;|| Es wird ein Schieberegler angezeigt um den Parameter auszuwählen. Dabei werden als Zusatzparameter Minimum, Schrittweite und Maximum angegeben.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;colorpicker&#039;&#039;&#039; || &amp;lt;code&amp;gt;rgb:colorpicker,RGB&amp;lt;/code&amp;gt;|| Es wird ein Colorpicker angezeigt, der dem Anwender die Auswahl einer Farbe ermöglicht. Die genaue Parametersyntax kann man dem Artikel zum  [[Color#Colorpicker|Colorpicker]] entnehmen.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;multiple&#039;&#039;&#039; || &amp;lt;code&amp;gt;group:multiple,Telefon,Multimedia,Licht,Heizung&amp;lt;/code&amp;gt; || Es erscheint ein Auswahldialog, wo man verschiedene Werte durch klicken auswählen kann. Optional kann man in einem Freitext eigene Werte ergänzen. dieser Dialog wird bspw. bei der Raum-Auswahl (Attribut &amp;quot;room&amp;quot;) oder der Gruppen-Auswahl (Attribut &amp;quot;group&amp;quot;) in FHEMWEB genutzt. &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;sortable&#039;&#039;&#039; || &amp;lt;code&amp;gt;command:sortable,monday,tuesday,...&amp;lt;/code&amp;gt; || Es erscheint ein Auswahldialog, wo man verschiedene Werte auswählen und sortieren kann. Man kann dabei Werte durch Klicken auswählen und durch Drag&#039;n&#039;Drop sortieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Es gibt noch weitere solcher Widgets. Eine genaue Auflistung dazu findet sich in der {{Link2CmdRef|Anker=widgetOverride}} unter widgetOverride zu FHEMWEB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweise&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Damit in einer Eingabe bereits der aktuelle Wert vorbelegt bzw. in einer Auswahlliste der aktuelle Wert vorselektiert ist, muss es im Modul bzw. Gerät ein Reading mit dem gleichen Namen wie die Set-Option geben. Der Wert des gleichnamigen Readings wird dann als Vorbelegung / Vorselektion verwendet. &lt;br /&gt;
* Der User kann sich in der Raumübersicht nach wie vor via [[WebCmd|webCmd]] eine entsprechende Steuerung anlegen.&lt;br /&gt;
&lt;br /&gt;
==== X_Attr ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Attr($$$$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $cmd, $name, $attrName, $attrValue  ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
 &lt;br /&gt;
	return $error;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Attr-Funktion dient der Prüfung von Attributen, welche über den &amp;lt;code&amp;gt;attr&amp;lt;/code&amp;gt;-Befehl gesetzt werden können. Sobald versucht wird, ein Attribut für ein Gerät zu setzen, wird vorher die Attr-Funktion des entsprechenden Moduls aufgerufen um zu prüfen, ob das Attribut aus Sicht des Moduls korrekt ist.&lt;br /&gt;
Liegt ein Problem mit dem Attribut bzw. dem Wert vor, so muss die Funktion eine aussagekräftige Fehlermeldung zurückgeben, welche dem User angezeigt wird.&lt;br /&gt;
Sofern das übergebene Attribut samt Inhalt korrekt ist, gibt die Attr-Funktion den Wert &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurück. Erst dann wird das Attribut in der globalen Datenstruktur &amp;lt;code&amp;gt;%attr&amp;lt;/code&amp;gt; gespeichert und ist somit erst aktiv.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Attr($$$$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $cmd, $name, $attrName, $attrValue ) = @_;&lt;br /&gt;
    &lt;br /&gt;
  	# $cmd  - Vorgangsart - kann die Werte &amp;quot;del&amp;quot; (löschen) oder &amp;quot;set&amp;quot; (setzen) annehmen&lt;br /&gt;
	# $name - Gerätename&lt;br /&gt;
	# $attrName/$attrValue sind Attribut-Name und Attribut-Wert&lt;br /&gt;
    &lt;br /&gt;
	if ($cmd eq &amp;quot;set&amp;quot;) {&lt;br /&gt;
		if ($aName eq &amp;quot;Regex&amp;quot;) {&lt;br /&gt;
			eval { qr/$aVal/ };&lt;br /&gt;
			if ($@) {&lt;br /&gt;
				Log3 $name, 3, &amp;quot;X ($name) - Invalid regex in attr $name $aName $aVal: $@&amp;quot;;&lt;br /&gt;
				return &amp;quot;Invalid Regex $aVal: $@&amp;quot;;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return undef;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist es möglich auch übergebene Attributwerte zu verändern bzw. zu korrigieren, indem man im Parameterarray &amp;lt;code&amp;gt;@_&amp;lt;/code&amp;gt; den ursprünglichen Wert anpasst. Dies erfolgt im Beispiel über die Modifikation des Wertes mit Index 3 (entspricht dem 4. Element) im Parameterarray, also &amp;lt;code&amp;gt;$_[3]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Da das Attribut zum Zeitpunkt des Aufrufs der Attr-Funktion noch nicht gespeichert ist, wird der neue Wert zu diesem Zeitpunkt noch nicht via [[DevelopmentModuleAPI#AttrVal|AttrVal()]] zurückgegeben. Erst, wenn die Attr-Funktion mit &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; beendet ist, wird der neue Wert in FHEM gespeichert und steht dann via AttrVal() zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Die Attr-Funktion bekommt nicht den Hash der Geräteinstanz übergeben, da sie normalerweise keine Werte dort speichern muss, sondern lediglich das Attribut auf Korrektheit prüfen muss.&lt;br /&gt;
Im obigen Beispiel wird für ein Attribut mit Namen &amp;quot;Regex&amp;quot; geprüft ob der reguläre Ausdruck fehlerhaft ist. Sofern dieser OK ist, wird &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben und fhem.pl speichert den Wert des Attributs in &amp;lt;code&amp;gt;%attr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Attributnamen mit Platzhaltern&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls man Attribute in der [[#X_Initialize|Initialize]]-Funktion mit Platzhaltern definiert (Wildcard-Attribute) wie z.B.:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
    $hash-&amp;gt;{AttrList} =&lt;br /&gt;
      &amp;quot;reading[0-9]*Name &amp;quot; .&lt;br /&gt;
    # usw.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
dann können Anwender Attribute wie reading01Name, reading02Name etc. setzen. Leider funktioniert das bisher nicht durch Klicken in der Web-Oberfläche, da FHEMWEB nicht alle denkbaren Ausprägungen in einem Dropdown anbieten kann. Der Benutzer muss solche Attribute manuell über den &amp;lt;code&amp;gt;attr&amp;lt;/code&amp;gt;-Befehl eingeben.&lt;br /&gt;
&lt;br /&gt;
Man kann jedoch in der Attr-Funktion neu gesetzte Ausprägungen von Wildcard-Attributen an die gerätespezifische userattr-Variable anfügen. Dann können bereits gesetzte Attribute in FHEMWEB durch Klicken ausgewählt und geändert werden.&lt;br /&gt;
Dazu reicht ein Aufruf der Funktion [[DevelopmentModuleAPI#addToDevAttrList|addToDevAttrList()]]: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
    addToDevAttrList($name, $aName);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_Read ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Read ($)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die X_Read-Funktion wird aufgerufen, wenn ein dem Gerät zugeordneter Filedeskriptor (serielle Schnittstelle, TCP-Verbindung, ...) Daten zum Lesen bereitgestellt hat. Die Daten müssen nun eingelesen und interpretiert werden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird über eine serielle Schnittstelle (beziehungsweise über einen USB-To-Serial-Konverter) von einem angeschlossenen Gerät gelesen. Dazu werden die bisher verfügbaren Daten mit der Funktion [[DevIo#DevIo_SimpleRead()|DevIo_SimpleRead()]] gelesen. Da die Übertragung möglicherweise noch nicht vollständig ist, kann es sein, dass kurz darauf die X_Read-Funktion wieder aufgerufen wird und ein weiterer Teil oder der Rest der Daten gelesen werden kann.&lt;br /&gt;
Die Funktion muss daher prüfen ob schon alle erwarteten Daten angekommen sind und gegebenenfalls die bisher gelesenen Daten in einem eigenen Puffer (idealerweise in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;) zwischenspeichern (siehe auch [[DevIo#Hinweis bei der Datenverarbeitung (Buffering)|DevIo]]). Im Beispiel ist dies &amp;lt;code&amp;gt;$hash-&amp;gt;{helper}{BUFFER}&amp;lt;/code&amp;gt; an den die aktuell gelesenen Daten angehängt werden, bis die folgende Prüfung ein für das jeweilige Protokoll vollständige Frame erkennt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Read($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
	my $name = $hash-&amp;gt;{NAME};&lt;br /&gt;
	&lt;br /&gt;
	# einlesen der bereitstehenden Daten&lt;br /&gt;
	my $buf = DevIo_SimpleRead($hash);		&lt;br /&gt;
	return &amp;quot;&amp;quot; if ( !defined($buf) );&lt;br /&gt;
	Log3 $name, 5, &amp;quot;X ($name) - received data: &amp;quot;.$buf;    &lt;br /&gt;
&lt;br /&gt;
	# Daten in Hex konvertieren und an den Puffer anhängen&lt;br /&gt;
	$hash-&amp;gt;{helper}{BUFFER} .= unpack (&#039;H*&#039;, $buf);	&lt;br /&gt;
	Log3 $name, 5, &amp;quot;X ($name) - current buffer content: &amp;quot;.$hash-&amp;gt;{helper}{BUFFER};&lt;br /&gt;
&lt;br /&gt;
	# prüfen, ob im Buffer ein vollständiger Frame zur Verarbeitung vorhanden ist.&lt;br /&gt;
	if ($hash-&amp;gt;{helper}{BUFFER} =~ &amp;quot;ff1002(.{4})(.*)1003(.{4})ff(.*)&amp;quot;) {&lt;br /&gt;
	...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die zu lesenden Nutzdaten können dann je nach Protokoll des Geräts beispielsweise an einer festgelegten Stelle im Frame (dann in &amp;lt;code&amp;gt;$hash-&amp;gt;{helper}{BUFFER}&amp;lt;/code&amp;gt;) stehen oder aus dem Kontext mit einem Regex-Match extrahiert werden und via [[DevelopmentModuleAPI#Readings_.2F_Events|Reading-Funktionen]] in Readings gespeichert werden (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Der Rückgabewert der Read-Funktion wird nicht geprüft und hat daher keinerlei Bedeutung.&lt;br /&gt;
&lt;br /&gt;
==== X_Ready ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Ready ($)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
    &lt;br /&gt;
	return $success;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wird im Main-Loop aufgerufen falls das Modul in der globalen Liste &amp;lt;code&amp;gt;%readyfnlist&amp;lt;/code&amp;gt; existiert. Diese Funktion hat, je nachdem auf welchem OS FHEM ausgeführt wird, unterschiedliche Aufgaben:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;UNIX-artiges Betriebssystem:&#039;&#039;&#039; prüfen, ob eine Verbindung nach einem Verbindungsabbruch wieder aufgebaut werden kann. Sobald der Verbindungsaufbau erfolgreich war, muss die Funktion einen erfolgreichen Wahrheitswert zurückliefern (z.B. &amp;quot;1&amp;quot;) und den eigenen Eintrag entsprechend aus &amp;lt;code&amp;gt;%readyfnlist&amp;lt;/code&amp;gt; löschen.&lt;br /&gt;
* &#039;&#039;&#039;Windows-Betriebssystem:&#039;&#039;&#039; prüfen, ob lesbare Daten für ein serielles Device (via COM1, COM2, ...) vorliegen. Sofern lesbare Daten vorliegen, muss Funktion einen erfolgreichen Wahrheitswert zurückliefern (z.B. &amp;quot;1&amp;quot;). Zusätzlich dazu muss die Funktion, wie bei UNIX-artigen Betriebssystem, ebenfalls bei einem Verbindungsabbruch einen neuen Verbindungsversuch initiieren. Der Eintrag in &amp;lt;code&amp;gt;%readyfnlist&amp;lt;/code&amp;gt; bleibt solange erhalten, bis die Verbindung seitens FHEM beendet wird.&lt;br /&gt;
&lt;br /&gt;
Der Windows-spezifische Teil zur Datenprüfung ist dabei nur zu implementieren, wenn das Modul über eine serielle Verbindung kommuniziert.&lt;br /&gt;
&lt;br /&gt;
Bei der Nutzung des Moduls [[DevIo]] wird dem Modulentwickler der Umgang mit &amp;lt;code&amp;gt;%readyfnlist&amp;lt;/code&amp;gt; abgenommen, da DevIo sich selbst um die entsprechenden Einträge kümmert und diese selbstständig wieder entfernt.&lt;br /&gt;
&lt;br /&gt;
In der Regel sieht eine Ready-Funktion immer gleich aus.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Ready($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
      &lt;br /&gt;
	# Versuch eines Verbindungsaufbaus, sofern die Verbindung beendet ist.&lt;br /&gt;
	return DevIo_OpenDev($hash, 1, undef ) if ( $hash-&amp;gt;{STATE} eq &amp;quot;disconnected&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
	# This is relevant for Windows/USB only&lt;br /&gt;
	if(defined($hash-&amp;gt;{USBDev})) {&lt;br /&gt;
		my $po = $hash-&amp;gt;{USBDev};&lt;br /&gt;
		my ( $BlockingFlags, $InBytes, $OutBytes, $ErrorFlags ) = $po-&amp;gt;status;&lt;br /&gt;
		return ( $InBytes &amp;gt; 0 );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_Notify ====&lt;br /&gt;
&lt;br /&gt;
Die X_Notify-Funktion wird aus der Funktion [[DevelopmentModuleAPI#DoTrigger|DoTrigger()]] in fhem.pl heraus aufgerufen sobald ein Modul Events erzeugt hat. Damit kann ein Modul auf Events anderer Module reagieren. Typische Beispiele sind dabei das [[FileLog]]-Modul oder das [[notify]]-Modul.&lt;br /&gt;
&lt;br /&gt;
Die Notify-Funktion bekommt dafür zwei Hash-Referenzen übergeben: den Hash des eigenen Geräts und den Hash des Geräts, das die Events erzeugt hat. &lt;br /&gt;
Über den Hash des eigenen Geräts kann die Notify-Funktion beispielsweise auf die Internals oder Attribute des eigenen Geräts zugreifen.&lt;br /&gt;
Über den Hash des Gerätes und der [[DevelopmentModuleAPI#deviceEvents|deviceEvents()]]-Funktion kann man auf die generierten Events zugreifen. Über den zweiten Parameter dieser Routine lässt sich bestimmen ob für das Reading &amp;lt;code&amp;gt;state&amp;lt;/code&amp;gt; ein &#039;normales&#039; Event (d.h. in der form &amp;lt;code&amp;gt;state: &amp;lt;wert&amp;gt;&amp;lt;/code&amp;gt;) erzeugen soll (Wert: 1) oder ob z.b. aus Gründen der Rückwärtskompatibilität ein Event ohne &amp;lt;code&amp;gt;state: &amp;lt;/code&amp;gt; erzeugt werden soll. Falls dem Anwender die Wahl des verwendeten Formats überlassen werden soll ist hierzu das {{Link2CmdRef|Anker=addStateEvent|Lang=de|Label=addStateEvent-Attribut}} vorzusehen.&lt;br /&gt;
&lt;br /&gt;
Der direkte Zugriff auf &amp;lt;code&amp;gt;$hash-&amp;gt;{CHANGED}&amp;lt;/code&amp;gt; ist nicht mehr zu empfehlen.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Notify($$)&lt;br /&gt;
{&lt;br /&gt;
  my ($own_hash, $dev_hash) = @_;&lt;br /&gt;
  my $ownName = $own_hash-&amp;gt;{NAME}; # own name / hash&lt;br /&gt;
&lt;br /&gt;
  return &amp;quot;&amp;quot; if(IsDisabled($ownName)); # Return without any further action if the module is disabled&lt;br /&gt;
&lt;br /&gt;
  my $devName = $dev_hash-&amp;gt;{NAME}; # Device that created the events&lt;br /&gt;
&lt;br /&gt;
  my $events = deviceEvents($dev_hash,1);&lt;br /&gt;
  return if( !$events );&lt;br /&gt;
&lt;br /&gt;
  foreach my $event (@{$events}) {&lt;br /&gt;
    $event = &amp;quot;&amp;quot; if(!defined($event));&lt;br /&gt;
&lt;br /&gt;
    # Examples:&lt;br /&gt;
    # $event = &amp;quot;readingname: value&amp;quot; &lt;br /&gt;
    # or&lt;br /&gt;
    # $event = &amp;quot;INITIALIZED&amp;quot; (for $devName equal &amp;quot;global&amp;quot;)&lt;br /&gt;
    #&lt;br /&gt;
    # processing $event with further code&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Begrenzung der Aufrufe auf bestimmte Geräte&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da die Notify-Funktion für jedes definierte Gerät mit all seinen Events aufgerufen wird, muss sie in einer Schleife jedesmal prüfen und entscheiden, ob es mit dem jeweiligen Event etwas anfangen kann. Ein Gerät, das die Notify-Funktion implementiert, sieht dafür typischerweise einen regulären Ausdruck vor, welcher für die Filterung verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Wenn man nur gezielt von bestimmten Definitionen Events erhalten will, kann man diese auch in Form einer {{Link2CmdRef|Lang=de|Anker=devspec|Label=devspec}} in &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; angeben. Bspw. kann man in der Define-Funktion diesen Wert setzen. Dadurch wird die Notify-Funktion nur aufgerufen wenn eine der Definitionen, auf welche die devspec passt, ein Event erzeugt hat. Ein typischer Fall ist die Begrenzung von Events auf &amp;quot;global&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
in der Define-Funktion:&lt;br /&gt;
&lt;br /&gt;
$hash-&amp;gt;{NOTIFYDEV} = &amp;quot;global&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{NOTIFYDEV} = &amp;quot;global,Definition_.*&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{NOTIFYDEV} = &amp;quot;global,Definition_A,Definition_B&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{NOTIFYDEV} = &amp;quot;global,TYPE=CUL_HM&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies schont insbesondere bei grossen Installationen Ressourcen, da die Notify-Funktion nicht sämtliche Events, sondern nur noch Events der gewünschten Definitionen erhält. Dadurch erfolgen deutlich weniger Aufrufe der Notify-Funktion, was Systemressourcen schont.&lt;br /&gt;
&lt;br /&gt;
Sofern in der [[#X_Define|Define-Funktion]] eine Regexp als Argument übergeben wird, die ähnlich wie beim Modul [[notify]] auf Events wie &amp;lt;code&amp;gt;&amp;amp;lt;Definitionsname&amp;amp;gt;&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;&amp;amp;lt;Definitionsname&amp;amp;gt;:&amp;amp;lt;Event&amp;amp;gt;&amp;lt;/code&amp;gt; reagiert, so sollte man in der Define-Funktion die Funktion [[DevelopmentModuleAPI#notifyRegexpChanged|notifyRegexpChanged()]] verwenden. Diese versucht einen passenden Eintrag für &amp;lt;code&amp;gt;$hash-&amp;gt;{NOTIFYDEV}&amp;lt;/code&amp;gt; basierend auf der übergebenen Regexp zu setzen, sofern dies möglich ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Reihenfolge für den Aufruf der Notify-Funktion beeinflussen&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sobald ein Event ausgelöst wurde, stellt sich FHEM eine Liste aller relevanten Geräte-Hashes zusammen, welche via Notify-Funktion prüfen müssen, ob das Event relevant ist. Dabei wird die Liste nach &amp;lt;code&amp;gt;$hash-&amp;gt;{NTFY_ORDER}&amp;lt;/code&amp;gt; sortiert. Diese enthält ein Order-Präfix in Form einer Ganzzahl, sowie den Namen der Definition (Bsp: &amp;lt;code&amp;gt;&#039;&#039;&#039;50&#039;&#039;&#039;-Lampe_Wohnzimmer&amp;lt;/code&amp;gt;). Dadurch kann man jedoch nicht sicherstellen, dass Events von bestimmten Modulen zuerst verarbeitet werden.&lt;br /&gt;
&lt;br /&gt;
Wenn das eigene Modul bei der Eventverarbeitung gegenüber den anderen Modulen eine bestimmte Reihenfolge einhalten muss, kann man in der [[#X_Initialize|Initialize]]-Funktion durch Setzen von &amp;lt;code&amp;gt;$hash-&amp;gt;{NotifyOrderPrefix}&amp;lt;/code&amp;gt; diese Reihenfolge beeinflussen. Standardmäßig werden Module immer mit einem Order-Präfix von &amp;quot;50-&amp;quot; in FHEM registriert. Durch die Veränderung dieses Präfixes kann man das eigene Modul in der Reihenfolge gegenüber anderen Modulen bei der Eventverarbeitung beeinflussen. &lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Initialize($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
	&lt;br /&gt;
	$hash-&amp;gt;{NotifyOrderPrefix} = &amp;quot;45-&amp;quot;  # Alle Definitionen des Moduls X werden bei der Eventverarbeitung zuerst geprüft&lt;br /&gt;
	&lt;br /&gt;
	# oder...&lt;br /&gt;
	&lt;br /&gt;
	$hash-&amp;gt;{NotifyOrderPrefix} = &amp;quot;55-&amp;quot;  # Alle Definitionen des Moduls X werden bei der Eventverarbeitung als letztes geprüft&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Da dieses Präfix bei eventverarbeitenden Definitionen in &amp;lt;code&amp;gt;$hash-&amp;gt;{NTFY_ORDER}&amp;lt;/code&amp;gt; dem Definitionsnamen vorangestellt wird bewirkt es bei einer normalen aufsteigenden Sortierung nach &amp;lt;code&amp;gt;$hash-&amp;gt;{NTFY_ORDER}&amp;lt;/code&amp;gt; eine veränderte Reihenfolge. Alle Module die in der Initialize-Funktion nicht &amp;lt;code&amp;gt;$hash-&amp;gt;{NotifyOrderPrefix}&amp;lt;/code&amp;gt; explizit setzen, werden mit &amp;quot;50-&amp;quot; als Standardwert vorbelegt.&lt;br /&gt;
&lt;br /&gt;
==== X_Rename ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Rename($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $new_name, $old_name) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Rename-Funktion wird ausgeführt, nachdem ein Gerät umbenannt wurde. Auf diese Weise kann ein Modul auf eine Namensänderung reagieren, wenn das Gerät &amp;lt;code&amp;gt;$old_name&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;$new_name&amp;lt;/code&amp;gt; umbenannt wurde. Ein typischer Fall ist das Umsetzen der Namensänderungen bei Daten die mittels [[DevelopmentModuleAPI#setKeyValue|setKeyValue()]] gespeichert wurden. Hierbei müssen die Daten, welche unter dem alten Namen gespeichert sind, auf den neuen Namen geändert werden.&lt;br /&gt;
&lt;br /&gt;
Der Rename-Funktion wird lediglich der alte, sowie der neue Gerätename übergeben. Der Rückgabewert wird nicht ausgewertet.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Rename($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $new_name, $old_name ) = @_;&lt;br /&gt;
&lt;br /&gt;
	my $old_index = &amp;quot;Module_X_&amp;quot;.$old_name.&amp;quot;_data&amp;quot;;&lt;br /&gt;
	my $new_index = &amp;quot;Module_X_&amp;quot;.$new_name.&amp;quot;_data&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	my ($err, $data) = getKeyValue($old_index);&lt;br /&gt;
	return undef unless(defined($old_pwd));&lt;br /&gt;
&lt;br /&gt;
	setKeyValue($new_index, $data);&lt;br /&gt;
	setKeyValue($old_index, undef);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_DelayedShutdown ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_DelayedShutdown($)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
&lt;br /&gt;
	return $delay_needed;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Mit der X_DelayedShutdown Funktion kann eine Definition das Stoppen von FHEM verzögern um asynchron hinter sich aufzuräumen. Dies kann z.B. der ordnungsgemäße Verbindungsabbau mit dem physikalischen Gerät sein (z.B. Session beenden, Logout, etc.), welcher mehrfache Requests/Responses benötigt. Als Übergabeparameter wird der Geräte-Hash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; bereitgestellt. Je nach Rückgabewert &amp;lt;code&amp;gt;$delay_needed&amp;lt;/code&amp;gt; wird der Stopp von FHEM verzögert. Ist ein verzögerter Stopp von FHEM notwendig, darf der Rückgabewert in diesem Fall nicht &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; sein.&lt;br /&gt;
&lt;br /&gt;
Im Unterschied zur [[#X_Shutdown|Shutdown]]-Funktion steht vor einem bevorstehenden Stopp von FHEM für einen User-konfigurierbaren Zeitraum (global-Attribut: &amp;lt;code&amp;gt;maxShutdownDelay&amp;lt;/code&amp;gt; / Standard: 10 Sekunden) weiterhin die asynchrone FHEM Infrastruktur ([[DevIo]]/[[#X_Read|Read]]-Funktion und [[DevelopmentModuleAPI#InternalTimer|InternalTimer]]) zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Sobald alle nötigen Maßnahmen erledigt sind, muss der Abschluss mit [[DevelopmentModuleAPI#CancelDelayedShutdown|CancelDelayedShutdown(&amp;lt;code&amp;gt;$name&amp;lt;/code&amp;gt;)]] an FHEM zurückgemeldet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_DelayedShutdown($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
&lt;br /&gt;
	# Aufräumen starten&lt;br /&gt;
	&lt;br /&gt;
	return 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_Shutdown ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Shutdown ($)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Mit der X_Shutdown Funktion kann ein Modul Aktionen durchführen bevor FHEM gestoppt wird. Dies kann z.B. der ordnungsgemäße Verbindungsabbau mit dem physikalischen Gerät sein (z.B. Session beenden, Logout, etc.). Nach der Ausführung der Shutdown-Fuktion wird FHEM sofort beendet. Falls vor dem Herunterfahren von FHEM asynchrone Kommunikation (via [[DevIo]]/[[#X_Read|X_Read]]) notwendig ist um eine vorhandene Verbindung sauber zu beenden, sollte man [[#X_DelayedShutdownFn|X_DelayedShutdownFn]] verwenden.&lt;br /&gt;
&lt;br /&gt;
Als Übergabeparameter wird der Geräte-Hash bereitgestellt. Der Rückgabewert einer Shutdown-Funktion wird nicht ausgewertet und ist daher irrelevant.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Shutdown($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
&lt;br /&gt;
	# Verbindung schließen&lt;br /&gt;
	DevIo_CloseDev($hash);&lt;br /&gt;
	return undef;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Funktionen für zweistufiges Modulkonzept ===&lt;br /&gt;
&lt;br /&gt;
Für das [[#Zweistufiges_Modell_für_Module|zweistufige Modulkonzept]] gibt es weiterhin:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left&amp;quot; | Funktionsname !! style=&amp;quot;text-align:left&amp;quot; class=&amp;quot;unsortable&amp;quot; | Kurzbeschreibung&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Parse|X_Parse]] || Zustellen von Daten via [[DevelopmentModuleAPI#Dispatch|Dispatch()]] vom physischen Modul zum logischen Modul zwecks der Verarbeitung.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Write|X_Write]]|| Zustellen von Daten via [[DevelopmentModuleAPI#Dispatch|IOWrite()]] vom logischen zum physischen Modul um diese an die Hardware weiterzureichen.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Fingerprint|X_Fingerprint]] || Rückgabe eines &amp;quot;Fingerabdrucks&amp;quot; einer Nachricht. Dient der Erkennung von Duplikaten im Rahmen von [[DevelopmentModuleAPI#Dispatch|Dispatch()]]. Kann im physischen, als auch logischen Modul benutzt werden.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Für das zweistufige Modulkonzept muss in einem logischen Modul eine [[#X_Parse|Parse]]-Funktion im Modul-Hash registriert werden. In einem physikalischen Modul muss eine [[#X_Write|Write]]-Funktion registriert sein. Diese dienen dem Datenaustausch in beide Richtungen und werden von dem jeweils anderen Modul indirekt aufgerufen.&lt;br /&gt;
&lt;br /&gt;
In der [[#X_Initialize|Initialize]]-Funktion werden diese wie folgt definiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$hash-&amp;gt;{ParseFn}       = &amp;quot;X_Parse&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{WriteFn}       = &amp;quot;X_Write&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{FingerprintFn} = &amp;quot;X_Fingerprint&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktionen werden in diesem Abschnitt genauer beschrieben.&lt;br /&gt;
&lt;br /&gt;
==== X_Parse ====&lt;br /&gt;
{{Randnotiz|RNTyp=Info|RNText=&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;u&amp;gt;&#039;&#039;&#039;ACHTUNG&#039;&#039;&#039;:&amp;lt;/u&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
Dieser Abschnitt geht davon aus, dass das Modul mit dem Namen &amp;quot;X&amp;quot; ein &#039;&#039;&#039;logisches Modul&#039;&#039;&#039; im Sinne des zweistufigen Modulkonzepts ist, also Daten mit einem übergeordneten, physikalischen Modul austauscht.}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Parse ($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $io_hash, $message) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
	&lt;br /&gt;
	return $found;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion X_Parse wird aufgerufen, sobald von dem IO-Gerät &amp;lt;code&amp;gt;$io_hash&amp;lt;/code&amp;gt; eine Nachricht &amp;lt;code&amp;gt;$message&amp;lt;/code&amp;gt; via [[DevelopmentModuleAPI#Dispatch|Dispatch()]] zur Verarbeitung angefragt wird. Die Parse-Funktion muss dann prüfen, zu welcher Gerätedefinition diese Nachricht gehört und diese entsprechend verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise enthält eine Nachricht immer eine Komponente durch welche sich die Nachricht einem Gerät zuordnen lässt (z.B. Adresse, ID-Nummer, ...). Eine solche Identifikation sollte man im Rahmen der [[#X_Define|Define]]-Funktion im logischen Modul an geeigneter Stelle speichern, um in der Parse-Funktion eine einfache Zuordnung von Adresse/ID einer Nachricht zur entsprechenden Gerätedefinition zu haben. Dazu wird in der Regel im Modul-Hash im modulspezifischen Bereich eine Liste &amp;lt;code&amp;gt;defptr&amp;lt;/code&amp;gt; (Definition Pointer) geführt, welche jede eindeutige Adresse/ID dem entsprechenden Geräte-Hash zuordnet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sub X_Define ($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $def) = @_;&lt;br /&gt;
	my @a = split(&amp;quot;[ \t][ \t]*&amp;quot;, $def);&lt;br /&gt;
	my $name = $a[0];&lt;br /&gt;
&lt;br /&gt;
	...&lt;br /&gt;
	&lt;br /&gt;
	# erstes Argument ist die eindeutige Geräteadresse&lt;br /&gt;
	my $address = $a[1];&lt;br /&gt;
&lt;br /&gt;
	# Adresse rückwärts dem Hash zuordnen (für ParseFn)&lt;br /&gt;
	$modules{X}{defptr}{$address} = $hash;&lt;br /&gt;
&lt;br /&gt;
	...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf Basis dieses Definition Pointers kann die Parse-Funktion nun sehr einfach prüfen, ob für die empfangene Nachricht bereits eine entsprechende Gerätedefinition existiert. Sofern diese existiert, kann die Nachricht entsprechend verarbeitet werden. Sollte jedoch keine passende Gerätedefinition zu der empfangenen Nachricht existieren, so muss die Parse-Funktion den Gerätenamen &amp;quot;UNDEFINED&amp;quot; zusammen mit den Argumenten für einen &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Befehl zurückgeben, welcher ein passendes Gerät in FHEM anlegen würde (durch [[autocreate]]).&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sub X_Parse ($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $io_hash, $message) = @_;&lt;br /&gt;
	&lt;br /&gt;
	# Die Stellen 10-15 enthalten die eindeutige Identifikation des Geräts&lt;br /&gt;
	my $address = substr($message, 10, 5); &lt;br /&gt;
&lt;br /&gt;
	# wenn bereits eine Gerätedefinition existiert (via Definition Pointer aus Define-Funktion)&lt;br /&gt;
	if(my $hash = $modules{X}{defptr}{$address}) &lt;br /&gt;
	{&lt;br /&gt;
		...  # Nachricht für $hash verarbeiten&lt;br /&gt;
		&lt;br /&gt;
		# Rückgabe des Gerätenamens, für welches die Nachricht bestimmt ist.&lt;br /&gt;
		return $hash-&amp;gt;{NAME}; &lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		# Keine Gerätedefinition verfügbar&lt;br /&gt;
		# Daher Vorschlag define-Befehl: &amp;lt;NAME&amp;gt; &amp;lt;MODULNAME&amp;gt; &amp;lt;ADDRESSE&amp;gt;&lt;br /&gt;
		return &amp;quot;UNDEFINED X_&amp;quot;.$address.&amp;quot; X $address&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_Write ====&lt;br /&gt;
{{Randnotiz|RNTyp=Info|RNText=&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;u&amp;gt;&#039;&#039;&#039;ACHTUNG&#039;&#039;&#039;:&amp;lt;/u&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
Dieser Abschnitt geht davon aus, dass das Modul mit dem Namen &amp;quot;X&amp;quot; ein &#039;&#039;&#039;physisches Modul&#039;&#039;&#039; im Sinne des zweistufigen Modulkonzepts ist, also Daten mit untergeordneten logischen Modulen austauscht. }}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Write ($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, @arguments) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
	&lt;br /&gt;
	return $return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Write-Funktion wird durch die Funktion [[DevelopmentModuleAPI#IOWrite|IOWrite()]] aufgerufen, sobald eine logische Gerätedefinition Daten per IO-Gerät an die Hardware übertragen möchte. Dazu kümmert sich die Write-Funktion um die Übertragung der Nachricht in geeigneter Form an die verbundene Hardware. Als Argumente wird der Hash des physischen Gerätes übertragen, sowie alle weiteren Argumente, die das logische Modul beim Aufruf von IOWrite() mitgegeben hat. Im Normalfall ist das ein Skalar mit der zu sendenden Nachricht in Textform. Es kann aber auch sein, dass weitere Daten zum Versand notwendig sind (evtl. Schlüssel, Session-Key, ...). Daher ist die Parametersyntax einer zu schreibenden Nachricht via IOWrite-/Write-Funktion zwischen logischem und physikalischem Modul abzustimmen.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Write ($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $message, $address) = @_;&lt;br /&gt;
	&lt;br /&gt;
	DevIo_SimpleWrite($hash, $address.$message, 2);&lt;br /&gt;
&lt;br /&gt;
	return undef;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_Fingerprint ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Fingerprint($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $io_name, $msg ) = @_;&lt;br /&gt;
 &lt;br /&gt;
	...&lt;br /&gt;
 &lt;br /&gt;
	return ( $io_name, $fingerprint );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Fingerprint-Funktion dient der Erkennung von Duplikaten empfangener Nachrichten. Diese Funktion kann dabei sowohl im physischen, als auch im logischen Modul implementiert sein - je nachdem auf welcher Ebene man für eine Nachricht einen Fingerprint bilden kann. &lt;br /&gt;
&lt;br /&gt;
Als Parameter wird der Name des IO-Geräts &amp;lt;code&amp;gt;$io_name&amp;lt;/code&amp;gt; übergeben, sowie die Nachricht &amp;lt;code&amp;gt;$msg&amp;lt;/code&amp;gt;, welche empfangen wurde. Nun muss aus dieser Nachricht ein eindeutiger Fingerprint gebildet werden. Dies bedeutet, dass alle variablen Inhalte, die aufgrund des Empfangs dieser Nachricht über unterschiedliche IO-Geräte enthalten sein können, entfernt werden müssen. Dies können bspw. Empfangsadressen von IO-Geräten sein oder Session-ID&#039;s die in der Nachricht enthalten sind. Alle Fingerprints sämtlicher Nachrichten, die innerhalb der letzten 500 Millisekunden (konfigurierbar via &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; Attribut &amp;lt;code&amp;gt;dupTimeout&amp;lt;/code&amp;gt;) empfangen wurden, werden gegen diesen generierten Fingerprint getestet. Sollte innerhalb dieser Zeit bereits eine Nachricht mit diesem Fingerprint verarbeitet worden sein, so wird sie als Duplikat erkannt und nicht weiter verarbeitet. In diesem Fall gibt [[DevelopmentModuleAPI#Dispatch|Dispatch()]] den Namen der Gerätedefinition zurück, welche eine Nachricht mit dem selben Fingerprint bereits verarbeitet hat. Es erfolgt dann kein Aufruf der [[#X_Parse|Parse]]-Funktion.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Fingerprint($$)&lt;br /&gt;
{&lt;br /&gt;
  my ( $io_name, $msg ) = @_;&lt;br /&gt;
&lt;br /&gt;
  substr( $msg, 2, 2, &amp;quot;--&amp;quot; ); # entferne Empfangsadresse&lt;br /&gt;
  substr( $msg, 4, 1, &amp;quot;-&amp;quot; );  # entferne Hop-Count&lt;br /&gt;
&lt;br /&gt;
  return ( $io_name, $msg );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es wird zuerst, sofern implementiert, die Fingerprint-Funktion des physischen Moduls aufgerufen. Sollte sich hierdurch kein Duplikat erkennen lassen, wird die Fingerprint-Funktion jedes möglichen geladenen logischen Moduls aufgerufen, sofern implementiert. &lt;br /&gt;
&lt;br /&gt;
Sollte sowohl im physischen, als auch im logischen Modul keine Fingerprint-Funktion implementiert sein, so wird keinerlei Duplikatserkennung durchgeführt.&lt;br /&gt;
&lt;br /&gt;
=== FHEMWEB-spezifische Funktionen ===&lt;br /&gt;
&lt;br /&gt;
FHEMWEB bietet Modul-Autoren die Möglichkeit an durch spezielle Funktionsaufrufe in Modulen, eigene HTML-Inhalte zu verwenden. Dadurch können in Verbindung mit zusätzlichem JavaScript komplexe Dialoge/Inhalte/Steuermöglichkeiten dargestellt werden. &lt;br /&gt;
&lt;br /&gt;
Eine genaue Auflistung aller FHEMWEB-spezifischen Funktionsaufrufe gibt es in dem separaten Artikel [[DevelopmentFHEMWEB]]&lt;br /&gt;
&lt;br /&gt;
=== sonstige Funktionen ===&lt;br /&gt;
&lt;br /&gt;
In diesem Abschnitt werden weitere Funktionen behandelt die zum Teil aus FHEM, aber auch aus anderen Modulen aufgerufen werden. Sie sind dabei nur in speziellen Anwendungsfällen relevant. Hier eine Auflistung aller sonstigen Modulfunktionen:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Funktionsname !! class=&amp;quot;unsortable&amp;quot; | Kurzbeschreibung&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_DbLog_split|X_DbLog_split]] || Wird durch das Modul 93_DbLog.pm aufgerufen. Dient dem korrekten Split eines moduleigenen Events in Name/Wert/Einheit für die Nutzung einer Datenbank.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Except|X_Except]]|| Wird aufgerufen, sobald ein ein geöffneter Filedescriptor in [[#Wichtige_globale_Variablen_aus_fhem.pl|&amp;lt;code&amp;gt;%selectlist&amp;lt;/code&amp;gt;]], der unter &amp;lt;code&amp;gt;$hash-&amp;gt;{EXCEPT_FD}&amp;lt;/code&amp;gt; im Geräte-Hash gesetzt ist, einen Interrupt bzw. Exception auslöst.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Copy|X_Copy]]|| Wird durch das Modul 98_copy.pm aufgerufen im Rahmen des &amp;lt;code&amp;gt;copy&amp;lt;/code&amp;gt;-Befehls sobald ein Gerät kopiert wurde.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_State|X_State]]|| Wird aufgerufen im Rahmen des &amp;lt;code&amp;gt;setstate&amp;lt;/code&amp;gt;-Befehls bevor der Status einer Gerätedefinition bzw. eines zugehörigen Readings gesetzt wird.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_AsyncOutput|X_AsyncOutput]]|| Nur relevant für Module die via [[TcpServerUtils]] eine Client-Verbindung zu FHEM ermöglichen (z.B. FHEMWEB und telnet). Ermöglicht die asynchrone Ausgabe von Daten via [[DevelopmentModuleAPI#asyncOutput|asyncOutput()]] an einen einzelnen verbundenen Client.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_ActivateInform|X_ActivateInform]]|| Nur relevant für Module die via [[TcpServerUtils]] eine Client-Verbindung zu FHEM ermöglichen (z.B. FHEMWEB und telnet). Ermöglicht das Aktivieren des inform-Mechanismus zum Senden von Events für einen einzelnen verbundenen Client.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Authorize|X_Authorize]]|| Wird aufgerufen im Rahmen von [[DevelopmentModuleAPI#Authorized|Authorized()]] um eine gewünschte Vorgangs-Art zu autorisieren.&lt;br /&gt;
|-&lt;br /&gt;
| [[#X_Authenticate|X_Authenticate]]||  Wird aufgerufen im Rahmen von [[DevelopmentModuleAPI#Authenticate|Authenticate()]] um eine Authentifizierung zu prüfen und ggf. zu genehmigen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In der [[#X_Initialize|Initialize]]-Funktion werden diese wie folgt definiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$hash-&amp;gt;{DbLog_splitFn} = &amp;quot;X_DbLog_split&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{ExceptFn} = &amp;quot;X_Except&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{CopyFn} = &amp;quot;X_Copy&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{AsyncOutputFn} = &amp;quot;X_AsyncOutput&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{ActivateInformFn} = &amp;quot;X_ActivateInform&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{StateFn} = &amp;quot;X_State&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{AuthorizeFn} = &amp;quot;X_Authorize&amp;quot;;&lt;br /&gt;
$hash-&amp;gt;{AuthenticateFn} = &amp;quot;X_Authenticate&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Funktionen werden in diesem Abschnitt genauer beschrieben.&lt;br /&gt;
==== X_DbLog_split ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_DbLog_split ($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $event, $device_name ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
    &lt;br /&gt;
	return  ( $reading, $value, $unit );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die DbLog_split-Funktion wird durch das Modul [[DbLog]] aufgerufen, sofern der Nutzer DbLog benutzt. Sofern diese Funktion implementiert ist, kann der Modul-Autor das Auftrennen von Events in den Reading-Namen, -Wert und der Einheit selbst steuern. Andernfalls nimmt DbLog diese Auftrennung selber mittels Trennung durch Leerzeichen sowie vordefinierten Regeln zu verschiedenen Modulen vor. Je nachdem, welche Readings man in seinem Modul implementiert, passt diese standardmäßige Trennung jedoch nicht immer.&lt;br /&gt;
&lt;br /&gt;
Der Funktion werden folgende Eingangsparameter übergeben:&lt;br /&gt;
# Das generierte Event (Bsp: &amp;lt;code&amp;gt;temperature: 20.5 °C&amp;lt;/code&amp;gt;)&lt;br /&gt;
# Der Name des Geräts, welche das Event erzeugt hat (Bsp: &amp;lt;code&amp;gt;Temperatursensor_Wohnzimmer&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Es ist nicht möglich in der DbLog_split-Funktion auf die verarbeitende DbLog-Definition zu referenzieren.&lt;br /&gt;
&lt;br /&gt;
Als Rückgabewerte muss die Funktion folgende Werte bereitstellen:&lt;br /&gt;
# Name des Readings (Bsp: &amp;lt;code&amp;gt;temperature&amp;lt;/code&amp;gt;)&lt;br /&gt;
# Wert des Readings (Bsp: &amp;lt;code&amp;gt;20.5&amp;lt;/code&amp;gt;)&lt;br /&gt;
# Einheit des Readings (Bsp: &amp;lt;code&amp;gt;°C&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_DbLog_splitFn($$)&lt;br /&gt;
{&lt;br /&gt;
	my ($event, $device) = @_;&lt;br /&gt;
	my ($reading, $value, $unit);&lt;br /&gt;
        my $devhash = $defs{$device}&lt;br /&gt;
&lt;br /&gt;
	if($event =~ m/temperature/) {&lt;br /&gt;
	   $reading = &#039;temperature&#039;;&lt;br /&gt;
	   $value = substr($event,12,4);&lt;br /&gt;
	   $unit = &#039;°C&#039;;&lt;br /&gt;
	}   &lt;br /&gt;
        &lt;br /&gt;
        return ($reading, $value, $unit);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_Except ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Except ($)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die X_Except-Funktion wird durch fhem.pl aufgerufen, wenn die Gerätedefinition &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;[[#Wichtige_globale_Variablen_aus_fhem.pl|%selectlist]]&amp;lt;/code&amp;gt; aufgeführt ist und der Filedeskriptor in &amp;lt;code&amp;gt;$hash-&amp;gt;{EXCEPT_FD}&amp;lt;/code&amp;gt; eine Exception bzw. Interrupt auslöst. &lt;br /&gt;
&lt;br /&gt;
Der Rückgabewert wird nicht ausgewertet und ist daher irrelevant.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
use IO::File;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
sub X_Except ($)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	# Filehandle aus Filedescriptor erstellen&lt;br /&gt;
	my $filehandle = IO::File-&amp;gt;new_from_fd($hash-&amp;gt;{EXCEPT_FD}, &#039;r&#039;);&lt;br /&gt;
	seek($filehandle,0,0);	&lt;br /&gt;
&lt;br /&gt;
	# aktuellen Inhalt auslesen&lt;br /&gt;
	my $current_value = $filehandle-&amp;gt;getline;&lt;br /&gt;
&lt;br /&gt;
	if($current_value eq &amp;quot;1&amp;quot;)&lt;br /&gt;
	{&lt;br /&gt;
		...&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		...&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_Copy ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Copy ($)&lt;br /&gt;
{&lt;br /&gt;
	my ( $old_name, $new_name ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die X_Copy-Funktion wird durch das Modul [[copy]] aufgerufen nachdem ein Nutzer eine Gerätedefinition über den Befehl &amp;lt;code&amp;gt;copy&amp;lt;/code&amp;gt; kopiert hat. Dazu werden als Funktionsparameter die Definitionsnamen der alten und neuen Gerätedefinition übergeben. Es dient dazu zusätzliche Daten aus der zu kopierenden Gerätedefinition in die neue Definition zu übernehmen. Der Befehl &amp;lt;code&amp;gt;copy&amp;lt;/code&amp;gt; überträgt lediglich &amp;lt;code&amp;gt;$hash-&amp;gt;{DEF}&amp;lt;/code&amp;gt; in die neue Definition sowie sämtliche gesetzte Attribute. Weitere Daten müssen dann durch die X_Copy-Funktion übertragen werden. &lt;br /&gt;
&lt;br /&gt;
Die X_Copy-Funktion wird erst nach dem erfolgtem Kopiervorgang aufgerufen.&lt;br /&gt;
&lt;br /&gt;
Der Rückgabewert wird nicht ausgewertet und ist daher irrelevant.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sub X_Copy ($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $old_name, $new_name ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	my $old_hash = $defs{$old_name};&lt;br /&gt;
	my $new_hash = $defs{$new_name};&lt;br /&gt;
&lt;br /&gt;
	# copy also temporary session key&lt;br /&gt;
	$new_hash-&amp;gt;{helper}{SESSION_KEY} = $old_hash-&amp;gt;{helper}{SESSION_KEY};&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_AsyncOutput ====&lt;br /&gt;
{{Randnotiz|RNTyp=Info|RNText=&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Diese Funktion ist nur relevant, wenn man ein Frontend-Modul erstellt über das FHEM von einem Anwender bedient werden kann (FHEMWEB, telnet, yowsup, telegram, alexa-fhem, homebridge-fhem, tabletui, ...).}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_AsyncOutput ($)&lt;br /&gt;
{&lt;br /&gt;
	my ( $client_hash, $text ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
&lt;br /&gt;
	return $error;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion X_AsyncOutput wird durch [[DevelopmentModuleAPI#asyncOutput|asyncOutput()]] von anderen Modulen aufgerufen. Es erlaubt diesen anderen Modulen die Ausgabe von asynchronen Befehlsergebnissen &amp;lt;code&amp;gt;$text&amp;lt;/code&amp;gt; zuvor ausgeführter set-/get-Befehle an den entsprechenden Client (identifiziert durch den Client-Hash &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; der temporären Definition) zurückzugeben. &lt;br /&gt;
&lt;br /&gt;
Wenn ein Client einen set-/get-Befehl ausführt, wird der Client-Hash bei der Ausführung dieser Befehle an die jeweiligen Module übermittelt. Sobald ein Befehl ausgeführt wird, der seine Ausgabe asynchron ausführen möchte und die Client-Verbindung des Server-Moduls dies unterstützt (&amp;lt;code&amp;gt;$client_hash-&amp;gt;{canAsyncOutput}&amp;lt;/code&amp;gt; ist gesetzt), merkt sich das befehlsausführende Modul den Client-Hash und gibt das Ergebnis des Befehls zu späterer Zeit via [[DevelopmentModuleAPI#asyncOutput|asyncOutput()]] an den ursprünglichen Client zurück. Die Funktion X_AsyncOutput des Server-Moduls kümmert sich darum das Ergebnis dem entsprechenden Client in der notwendigen Form zuzustellen.&lt;br /&gt;
&lt;br /&gt;
Der Rückgabewert von X_AsyncOutput() wird als Rückgabewert für asyncOutput() verwendet. Man kann hier im Fehlerfall eine Fehlermeldung angeben und im Erfolgsfall &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;. Der Rückgabewert wird aber aktuell nicht ausgewertet.&lt;br /&gt;
&lt;br /&gt;
==== X_ActivateInform====&lt;br /&gt;
{{Randnotiz|RNTyp=Info|RNText=&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Diese Funktion ist nur relevant, wenn man ein Frontend-Modul erstellt über das FHEM von einem Anwender bedient werden kann (FHEMWEB, telnet, yowsup, telegram, alexa-fhem, homebridge-fhem, tabletui, ...).}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_ActivateInform($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $client_hash, $arg ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion X_ActivateInform wird aktuell nur durch den [[update]]-Befehl aufgerufen, sofern ein Client eines Frontend-Moduls diesen Befehl aufgerufen hat um den Inform-Mechanismus (Senden von Events) zu aktivieren. Dadurch wird im Falle von [[update]] die umgehende Anzeige der Logmeldungen für den ausführenden Client aktiviert. In [[FHEMWEB]] geschieht das über den Event-Monitor, bei telnet mit der direkten Ausgabe.&lt;br /&gt;
&lt;br /&gt;
Da diese Funktion aktuell nur speziell für den update-Befehl implementiert ist, kann man aktuell keine genaue Angaben zu den möglichen Werten von &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; geben. Dieser Parameter dient dazu genauer zu spezifizieren was exakt an Events an den entsprechenden Client &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; zu senden ist. Aktuell wird dazu die Parametersyntax des inform-Befehls verwendet (on|off|log|raw|timer|status).&lt;br /&gt;
&lt;br /&gt;
==== X_State ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_State($$$$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $time, $readingName, $value ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
&lt;br /&gt;
	return $error;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die X_State-Funktion wird durch fhem.pl aufgerufen, sobald über den Befehl &amp;lt;code&amp;gt;setstate&amp;lt;/code&amp;gt; versucht wird ein Wert für ein Reading oder den Status (&amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt;) einer Gerätedefinition zu setzen. Dieser Befehl wird primär beim Starten von FHEM aufgerufen sobald das State-File eingelesen wird. Je nachdem, ob im gegebenen Fall ein Reading oder der Definitionsstatus gesetzt wird, haben die Übergabeparameter verschiedene Werte:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Funktionsparameter!! Wert beim Setzen eines Readings !! Wert beim Setzen eines Definitionsstatus&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; || colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Die Hashreferenz der betreffenden Gerätedefinition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$time&amp;lt;/code&amp;gt;|| Der Zeitstempel auf welchen das Reading &amp;lt;code&amp;gt;$readingName&amp;lt;/code&amp;gt; gesetzt werden soll. Das Ergebnis entspricht dem Rückgabewert der Funktion || Der aktuelle Zeitstempel zum jetzigen Zeitpunkt.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$readingName&amp;lt;/code&amp;gt;|| Der Name des Readings, welches auf einen neuen Wert gesetzt werden soll. || Statischer Wert &amp;quot;STATE&amp;quot; um anzuzeigen, dass es sich um den Definitionsstatus handelt, welcher gesetzt werden soll (&amp;lt;code&amp;gt;$hash-&amp;gt;{STATE}&amp;lt;/code&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;$value&amp;lt;/code&amp;gt; || Den Wert, welchen das Reading &amp;lt;code&amp;gt;$readingName&amp;lt;/code&amp;gt; annehmen soll. || Den Wert, welchen die Gerätedefinition als Status annehmen soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Wenn via &amp;lt;code&amp;gt;setstate&amp;lt;/code&amp;gt; ein Reading gesetzt wird, kann die X_State-Funktion das Setzen dieses Readings durch die Rückgabe einer aussagekräftigen Fehlermeldung unterbinden. Sofern &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt; zurückgegeben wird, wird das entsprechende Reading auf den übergebenen Status gesetzt.&lt;br /&gt;
&lt;br /&gt;
Wenn via &amp;lt;code&amp;gt;setstate&amp;lt;/code&amp;gt; der Definitionsstatus gesetzt wird, wird die X_State-Funktion erst nach dem Setzen des Status aufgerufen. Man kann dabei zwar eine Fehlermeldung zurückgeben, der Status wird aber dennoch übernommen. Die Fehlermeldung wird lediglich dem Nutzer angezeigt.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_State($$$$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $time, $readingName, $value ) = @_;&lt;br /&gt;
&lt;br /&gt;
	return undef if($readingName &amp;quot;STATE&amp;quot; || $value ne &amp;quot;inactive&amp;quot;);&lt;br /&gt;
	readingsSingleUpdate($hash, &amp;quot;state&amp;quot;, &amp;quot;inactive&amp;quot;, 1);&lt;br /&gt;
	return undef;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== X_Authorize ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Authorize($$$$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $client_hash, $type, $arg ) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
 &lt;br /&gt;
	return $authorized;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Authorize-Funktion wird von fhem.pl aufgerufen um zu erfragen, ob ein bestimmter Client &amp;lt;code&amp;gt;$client_hash&amp;lt;/code&amp;gt; die Aktion &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; ausführen darf. Auf diese Weise können Module Einfluss nehmen, welcher User welche Funktionen in FHEM nutzen darf. Wenn ein Client eine Aktion ausführen möchte, werden alle Module, die eine Authorize-Funktion implementiert haben, gefragt, ob diese Aktion ausgeführt werden darf. Als Rückgabewert wird das Ergebnis der Überprüfung zurückgegeben, wobei &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (unbekannt / nicht zuständig), &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; (erlaubt) oder &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; (verboten) zurückgegeben werden können.&lt;br /&gt;
&lt;br /&gt;
Es gibt aktuell folgende &amp;lt;code&amp;gt;$type&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; Kombinationen, mit denen die Authorize-Funktion aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! $type !! $arg !! Überschrift&lt;br /&gt;
|- &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;&#039;&#039;&#039;$type&#039;&#039;&#039; = &amp;quot;cmd&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Befehlsausführung&#039;&#039;&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;&#039;&#039;&#039;$arg&#039;&#039;&#039; = &amp;quot;set Lampe on&amp;quot;&amp;lt;/code&amp;gt; || Jeglicher FHEM-Befehl, der ausgeführt werden soll, wird in &amp;lt;code&amp;gt;$arg&amp;lt;/code&amp;gt; hinterlegt, sodass innerhalb einer Authorize-Funktion der Befehl genauer geparst werden kann um zu entscheiden, ob dieser Befehl erlaubt ist, oder nicht.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;&#039;&#039;&#039;$arg&#039;&#039;&#039; = &amp;quot;perl&amp;quot;&amp;lt;/code&amp;gt; || Ausführen von Perl-Befehlen jeglicher Art. Der genaue Befehl wird dabei nicht an die Authorize-Funktion übergeben.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;{ReadingsVal(&amp;quot;Lampe&amp;quot;, &amp;quot;state&amp;quot;, &amp;quot;off&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;&#039;&#039;&#039;$arg&#039;&#039;&#039; = &amp;quot;shell&amp;quot;&amp;lt;/code&amp;gt; || Ausführen von Shell-Befehlen jeglicher Art. Der genaue Befehl wird dabei nicht an die Authorize-Funktion übergeben.&lt;br /&gt;
&lt;br /&gt;
Bsp: &amp;lt;code&amp;gt;&amp;quot;/opt/fhem/myScript.sh&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;&#039;&#039;&#039;$type&#039;&#039;&#039; = &amp;quot;devicename&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Sichtbarkeit von Geräten/Definitionen&#039;&#039; &lt;br /&gt;
| style=&amp;quot;white-space: nowrap;&amp;quot; |  &amp;lt;code&amp;gt;&#039;&#039;&#039;$arg&#039;&#039;&#039; = &amp;quot;Licht_Wohnzimmer&amp;quot;&amp;lt;/code&amp;gt; || Sichtbarkeit des jeweiligen Gerät/Definition in FHEM. Dies bedeutet konkret die Auffindbarkeit im &amp;lt;code&amp;gt;list&amp;lt;/code&amp;gt;-Befehl, sowie der Suche via [[DevelopmentModuleAPI#devspec2array|devspec2array()]]. Wird eine solche Anfrage durch die Authorize-Funktion abgelehnt, ist das entsprechende Gerät bzw. Definition für den jeweiligen Client nicht sichtbar.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== X_Authenticate ====&lt;br /&gt;
{{Link2Forum|Topic=72757|Message=644098}}&lt;br /&gt;
&lt;br /&gt;
== Bereitstellen eines eigenen Befehls (Befehlsmodul) ==&lt;br /&gt;
&lt;br /&gt;
Ein Modul kann primär einen neuen FHEM-Befehl bereitstellen. Man spricht in so einem Fall nicht von einem Gerätemodul, sondern einem Befehlsmodul. Ein solches Befehlsmodul stellt nur einen einzelnen Befehl bereit, der dem Modulnamen entsprechen muss. Nur, wenn der Modulname dem Befehlsname entspricht, kann FHEM das Modul beim ersten Ausführen dieses unbekannten Befehls finden und nachladen.&lt;br /&gt;
&lt;br /&gt;
Der entsprechende Befehl wird dazu in der [[#X_Initialize|Initialize]]-Funktion im globalen Hash &amp;lt;code&amp;gt;[[DevelopmentModuleIntro#Wichtige_globale_Variablen_aus_fhem.pl|%cmds]]&amp;lt;/code&amp;gt; registriert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Initialize($$) {&lt;br /&gt;
&lt;br /&gt;
    $cmds{X} = { Fn           =&amp;gt; &amp;quot;CommandX&amp;quot;,&lt;br /&gt;
                 Hlp          =&amp;gt; &amp;quot;&amp;lt;argument1&amp;gt; [optional_argument2], print something very useful&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
                 # optionaler Filter für Clientmodule als regulärer Ausdruck&lt;br /&gt;
                 ClientFilter =&amp;gt; &amp;quot;FHEMWEB&amp;quot;&lt;br /&gt;
                };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird der neue Befehl &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; in FHEM registriert. Die Funktion mit dem Namen &amp;lt;code&amp;gt;CommandX&amp;lt;/code&amp;gt; setzt diesen Befehl innerhalb des Moduls um. Desweiteren wird eine kurze Aufrufsyntax mitgegeben, welche beim Aufruf des &amp;lt;code&amp;gt;help&amp;lt;/code&amp;gt;-Befehls dem Nutzer angezeigt wird um als Gedankenstütze zu dienen. Optional kann man mittels &amp;lt;code&amp;gt;ClientFilter&amp;lt;/code&amp;gt; (regulärer Ausdruck für Modulnamen) die Ausführbarkeit nur auf bestimmte Client-Module (wie FHEMWEB oder telnet) beschränken. &lt;br /&gt;
&lt;br /&gt;
Nun muss noch die Funktion &amp;lt;code&amp;gt;CommandX&amp;lt;/code&amp;gt; im Rahmen des Moduls implementiert werden, welche den Befehl &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; umsetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Perl&amp;quot;&amp;gt;&lt;br /&gt;
sub CommandX($$)&lt;br /&gt;
{&lt;br /&gt;
 	my ($client_hash, $arguments) = @_;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
	&lt;br /&gt;
	return $output;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei werden der Befehlsfunktion zwei Parameter übergeben. Zuerst die Hash-Referenz des aufrufenden Clients (sofern manuell ausgeführt, ansonsten &amp;lt;code&amp;gt;undef&amp;lt;/code&amp;gt;) zwecks Rechteprüfung via [[allowed|allowed-Definitionen]]. Anschließend folgen die Aufrufparameter als zusammenhängende Zeichenkette. Die Trennung der einzelnen Argumente obligt der Funktion (bspw. via [[DevelopmentModuleAPI#parseParams|parseParams()]]). Als Funktionsrückgabewert wird eine Ausgabemeldung erwartet, die dem Nutzer angezeigt werden soll.&lt;br /&gt;
&lt;br /&gt;
== Pollen von Geräten ==&lt;br /&gt;
Wenn Geräte von sich aus keine Informationen senden sondern abgefragt werden müssen, kann man im Modul die Funktion [[DevelopmentModuleAPI#InternalTimer|InternalTimer()]] verwenden um einen Funktionsaufruf zu einem späteren Zeitpunkt durchführen zu können. Man übergibt dabei den Zeitpunkt für den nächsten Aufruf, den Namen der Funktion, die aufgerufen werden soll, sowie den zu übergebenden Parameter. Als zu übergebender Parameter wird üblicherweise der Hash der betroffenen Geräteinstanz verwendet. Damit hat die aufgerufene Funktion Zugriff auf alle wichtigen Daten der Geräteinstanz. Eventuell zusätzlich benötigte Werte können einfach als weitere Internals über den Hash zugänglich gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Beispielsweise könnte man für das Abfragen eines Geräts in der [[#X_Define|Define]]-Funktion den Timer folgendermaßen setzen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
InternalTimer(gettimeofday()+2, &amp;quot;X_GetUpdate&amp;quot;, $hash);	&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternativ kann man auch in der [[#X_Notify|Notify]]-Funktion auf das Event &amp;lt;code&amp;gt;global:INITIALIZED&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;global:REREADCFG&amp;lt;/code&amp;gt; reagieren und erst dort, den Timer anstoßen, sobald die Konfiguration komplett eingelesen wurde. Dies ist insbesondere notwendig, wenn man sicherstellen will, dass alle Attribute aus der Konfiguration gesetzt sind, sobald man einen Status-Update initiiert.&lt;br /&gt;
&lt;br /&gt;
In der Funktion &amp;lt;code&amp;gt;X_GetUpdate&amp;lt;/code&amp;gt; selbst wird dann der Timer neu gesetzt, so dass nach einem Intervall die Funktion erneut aufgerufen wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_GetUpdate($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
	my $name = $hash-&amp;gt;{NAME};&lt;br /&gt;
	Log3 $name, 4, &amp;quot;X: GetUpdate called ...&amp;quot;;&lt;br /&gt;
	&lt;br /&gt;
	...&lt;br /&gt;
	&lt;br /&gt;
	# neuen Timer starten in einem konfigurierten Interval.&lt;br /&gt;
	InternalTimer(gettimeofday()+$hash-&amp;gt;{Interval}, &amp;quot;X_GetUpdate&amp;quot;, $hash);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Innerhalb der Funktion kann man nun das Gerät abfragen und die abgefragten Werte in Readings speichern. Falls das Abfragen der Werte jedoch zu einer Verzögerung und damit zu einer Blockade von FHEM führen kann, ist es möglich, in der GetUpdate-Funktion nur die Aufforderung zum Senden bestimmter Daten an das angeschlossene Gerät zu senden und dann das Lesen über die oben beschriebene [[#X_Read|Read]]-Funktion zu implementieren.&lt;br /&gt;
&lt;br /&gt;
Eine genaue Beschreibung der Timer-Funktion gibt es [[DevelopmentModuleAPI#Timer|hier im Wiki]]&lt;br /&gt;
&lt;br /&gt;
== Logging / Debugging ==&lt;br /&gt;
Um Innerhalb eines Moduls eine Log-Meldung in die FHEM-Logdatei zu schreiben, wird die Funktion [[DevelopmentModuleAPI#Log3|Log3()]] aufgerufen.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
Log3 $name, 3, &amp;quot;X ($name) - Problem erkannt ...&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Eine genaue Beschreibung zu der Funktion inkl. Aufrufparameter findet man [[DevelopmentModuleAPI#Log3|hier]]. Es ist generell ratsam in der Logmeldung sowohl den Namen des eigenen Moduls zu schreiben, sowie den Namen des Geräts, welche diese Logmeldung produziert, da die Meldung, so wie sie ist, direkt in das Logfile wandert und es für User ohne diese Informationen schwierig ist, die Meldungen korrekt zuzuordnen.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Log3() verwendet den Namen der Geräteinstanz um das &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;-Attribut zu prüfen. In der Regel wird bei Modulfunktionen jedoch immer nur der Gerätehash &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; übergeben. Um den Namen der Definition zu ermitteln ist es daher notwendig sich diesen aus dem Hash extrahieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
my $name = $hash-&amp;gt;{NAME};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um für eine einzelne Geräteinstanz das Verbose-Level zu erhöhen, ohne gleich für das gesamte FHEM den globalen Verbose-Level zu erhöhen und damit alle Meldungen zu erzeugen, kann man den Befehl &lt;br /&gt;
&amp;lt;code&amp;gt;attr &amp;lt;NAME&amp;gt; verbose&amp;lt;/code&amp;gt; verwenden. Beispielsweise &amp;lt;code&amp;gt;attr Lichtschalter_Wohnzimmer verbose 5&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logmeldungen sollten je nach Art und Wichtigkeit für den Nutzer in unterschiedlichen Loglevels erzeugt werden. Es gibt insgesamt 5 Stufen in denen geloggt werden kann. Standardmäßig steht der systemweite Loglevel (&amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt;-Attribut &amp;lt;code&amp;gt;verbose&amp;lt;/code&amp;gt;) auf der Stufe 3. Die Bedeutung der jeweiligen Stufen ist in der {{Link2CmdRef|Lang=de|Anker=verbose}} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Während der Entwicklung eines Moduls kann man für eigene Debug-Zwecke auch die Funktion [[DevelopmentModuleAPI#Debug|Debug()]] verwenden um schnell und einfach Debug-Ausgaben in das Log zu schreiben. Diese sollten in der endgültigen Fassung jedoch nicht mehr vorhanden sein. Sie dienen ausschließlich zum Debugging während der Entwicklung.&lt;br /&gt;
&lt;br /&gt;
Eine genaue Beschreibung der Log-Funktion gibt es [[DevelopmentModuleAPI#Logging|hier im Wiki]].&lt;br /&gt;
&lt;br /&gt;
== Zweistufiges Modell für Module ==&lt;br /&gt;
[[Datei:Zweistufiges Modulkonzept.jpg|mini|rechts|Schematische Darstellung am Beispiel CUL]]&lt;br /&gt;
Es gibt viele Geräte, welche die Kommunikation mit weiteren Geräten mit tlw. unterschiedlichen Protokollen ermöglichen. Das typischste Beispiel bietet hier der [[CUL]], welcher via Funk mit verschiedenen Protokollen weitere Geräte ansprechen kann (z.B. Aktoren, Sensoren, ...). Hier bildet ein Gerät eine Brücke durch die weitere Geräte in FHEM zugänglich gemacht werden können. Dabei werden über einen Kommunikationsweg (z.B. serielle Schnittstelle, TCP, ...) beliebig viele Geräte gesteuert. Typische Beispiele dazu sind:&lt;br /&gt;
&lt;br /&gt;
* [[CUL]]: stellt Geräte mit verschiedenen Kommunikationsprotokollen via Funk bereit (u.a. [[FS20]], [[HomeMatic]], [[Funk-Heizkörperregler_Kurz-Bedienungsanleitung_FHT|FHT]], [[MAX]], ...)&lt;br /&gt;
* [[HMLAN]]: stellt HomeMatic Geräte via Funk bereit&lt;br /&gt;
* [[MAX#MAXLAN|MAXLAN]]: stellt [[MAX|MAX!]] Geräte via Funk bereit&lt;br /&gt;
* [[PanStamp#panStick.2FShield|panStamp]]: stellt weitere panStamp Geräte via Funk bereit&lt;br /&gt;
&lt;br /&gt;
Dabei wird die Kommunikation in 2 Stufen unterteilt:&lt;br /&gt;
* physisches Modul - z.B. 00_CUL.pm - zuständig für die physikalische Kommunikation mit der Hardware. Empfangene Daten müssen einem logischen Modul zugeordnet werden.&lt;br /&gt;
* logische Modul(e) - z.B. 10_FS20.pm - interpretiert protokollspezifische Nachrichten. Sendet protokollspezifische Daten über das physische Modul an die Hardware.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;physisches Modul&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das physische Modul öffnet die Datenverbindung zum Gerät (z.B. CUL) und verarbeitet sämtliche Daten. Es kümmert sich um den Erhalt der Verbindung (bsp. durch Keep-Alives) und konfiguriert das Gerät so, dass eine Kommunikation mit allen weiteren Geräten möglich ist (bsp. Frequenz, Modulation, Kanal, etc.).&lt;br /&gt;
&lt;br /&gt;
Empfangene Nutzdaten werden als Zeichenkette über die Funktion [[DevelopmentModuleAPI#Dispatch|Dispatch()]] an logische Module weitergegeben.&lt;br /&gt;
&lt;br /&gt;
Das Modul stellt eine [[#Die_Match-Liste|Match-Liste]] bereit, anhand FHEM die Nachricht einem Modul zuordnen kann, sofern dieses noch nicht geladen sein sollte. Die Match-Liste enthält eine Liste von regulären Ausdrücken und ordnet diese einem Modul zu. Wenn eine Nachricht auf einen solchen regulären Ausdruck passt und das Modul noch nicht geladen ist, lädt FHEM dieses automatisch nach, zwecks Verarbeitung der Nachricht. &lt;br /&gt;
&lt;br /&gt;
Anhand einer bereitgestellten [[#Die_Client-Liste|Client-Liste]] (Auflistung von logischen Modulen) kann FHEM feststellen, welche logischen Module mit dem physischen Modul kommunizieren können. Nur die hier aufgelisteten, logischen Module werden beim Aufruf von [[DevelopmentModuleAPI#Dispatch|Dispatch()]] angesprochen.&lt;br /&gt;
&lt;br /&gt;
Das Modul stellt eine [[#X_Write|Write]]-Funktion zur Verfügung, über die logische Module Daten in beliebiger Form an die Hardware übertragen können. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;logisches Modul&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das logische Modul interpretiert die via Dispatch() übergebene Nachricht (Zeichenkette) durch eine bereitgestellte [[#X_Parse|Parse]]-Funktion und erzeugt entsprechende Readings/Events. Es stellt über &amp;lt;code&amp;gt;set&amp;lt;/code&amp;gt;-/&amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt;-Kommandos Steuerungsmöglichkeiten dem Nutzer zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Es stellt FHEM einen [[#Der_Match-Ausdruck|Match-Ausdruck]] (regulärer Ausdruck) zur Verfügung anhand [[DevelopmentModuleAPI#Dispatch|Dispatch()]] ermitteln kann, ob die Nachricht durch das logische Modul verarbeitet werden kann. Nur Nachrichten, welche auf diesen Ausdruck passen, werden an das logische Modul weitergegeben (Aufruf [[#X_Parse|Parse]]-Funktion).&lt;br /&gt;
&lt;br /&gt;
=== Die Client-Liste ===&lt;br /&gt;
&lt;br /&gt;
Die Client-Liste ist eine Auflistung von Modulnamen (genauer: regulären Ausdrücken die auf Modulnamen passen) die in einem physischen Modul gesetzt ist. Damit wird definiert, mit welchen logischen Modulen das physikalische Modul  kommunizieren kann. &lt;br /&gt;
&lt;br /&gt;
Eine Client-Liste ist eine Zeichenkette, welche aus allen logischen Modulnamen besteht. Die einzelnen Namen werden durch einen Doppelpunkt getrennt. Anstatt kompletter Modulnamen können auch reguläre Ausdrücke verwendet werden, die auf mehrere Modulnamen passen (z.B. &amp;lt;code&amp;gt;CUL_.*&amp;lt;/code&amp;gt; um die logischen Module CUL_HM, CUL_MAX, etc. zu verwenden).&lt;br /&gt;
&lt;br /&gt;
Bsp.: Die Client-Liste von dem Modul CUL lautet daher wie folgt:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
FS20:FHT.*:KS300:USF1000:BS:HMS:CUL_EM:CUL_WS:CUL_FHTTK:CUL_HOERMANN:ESA2000:CUL_IR:CUL_TX:Revolt:IT:UNIRoll:SOMFY:STACKABLE_CC:CUL_RFR:CUL_TCM97001:CUL_REDIRECT&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Alle hier aufgelisteten Module können über das Modul CUL Daten empfangen bzw. senden.&lt;br /&gt;
&lt;br /&gt;
Die Client-Liste hat generell folgende Funktion:&lt;br /&gt;
* Die Funktion [[DevelopmentModuleAPI#Dispatch|Dispatch()]] prüft nur Module, welche in der Client-Liste enthalten sind, ob diese die Nachricht verarbeiten können (Prüfung via [[#Der Match-Ausdruck|Match-Ausdruck]])&lt;br /&gt;
* Die Funktion [[DevelopmentModuleAPI#AssignIoPort|AssignIoPort()]] prüft anhand sämtlicher Client-Listen in FHEM, welches IO-Gerät für ein logisches Gerät nutzbar ist.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird die Client-Liste in der [[#X_Initialize|Initialize]]-Funktion im Modul-Hash gesetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Initialize($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
	...&lt;br /&gt;
	$hash-&amp;gt;{Clients} = &amp;quot;FS20:KS300:FHT.*&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man kann die Client-Liste jedoch auch pro physikalisches Gerät setzen. Eine gesetzte Client-Liste in einem Gerät hat immer Vorrang vor der Liste im Modul-Hash. Eine gerätespezifische Client-Liste wird dann verwendet, wenn bspw. ein Gerät je nach Konfiguration nur bestimmte logische Module bedienen kann. Bspw. kann ein CUL je nach RF-Einstellungen FS20, uvm. oder nur HomeMatic bedienen. In einem solchen Fall wird die Client-Liste im Geräte-Hash gesetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Define($$)&lt;br /&gt;
{&lt;br /&gt;
	my ( $hash, $def ) = @_;&lt;br /&gt;
	...&lt;br /&gt;
	$hash-&amp;gt;{Clients} = &amp;quot;CUL_HM&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In vielen Modulen, welche nach dem zweistufigem Konzept arbeiten, beginnt und endet die Client-Liste mit einem Doppelpunkt. Dies ist ein historisches Überbleibsel, da der Prüfmechanismus die Client-Liste früher auf das Vorhandensein von &amp;lt;code&amp;gt;&#039;&#039;&#039;&amp;lt;u&amp;gt;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;:&amp;lt;/font&amp;gt;&amp;lt;/u&amp;gt;&#039;&#039;&#039;&amp;amp;lt;Modulname&amp;amp;gt;&#039;&#039;&#039;&amp;lt;u&amp;gt;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;:&amp;lt;/font&amp;gt;&amp;lt;/u&amp;gt;&#039;&#039;&#039;&amp;lt;/code&amp;gt; prüfte. Dies ist nun nicht mehr notwendig. Die einzelnen Modulnamen müssen lediglich durch einen Doppelpunkt getrennt werden.&lt;br /&gt;
&lt;br /&gt;
=== Die Match-Liste ===&lt;br /&gt;
{{Randnotiz|RNTyp=Info|RNText=&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;u&amp;gt;&#039;&#039;&#039;ACHTUNG&#039;&#039;&#039;:&amp;lt;/u&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
Sämtliche regulären Ausdrücke in der Match-Liste werden &amp;quot;case insensitive&amp;quot; überprüft. Das bedeutet, dass Groß-/Kleinschreibung nicht berücksichtigt wird.&lt;br /&gt;
&lt;br /&gt;
Um dennoch in einem regulären Ausdruck auf Groß-/Kleinschreibung zu prüfen, kann man dieses mit dem Modifizierer &amp;lt;code&amp;gt;(?-i)&amp;lt;/code&amp;gt; wieder aktivieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
my %matchListFHEMduino = (&lt;br /&gt;
    ....&lt;br /&gt;
    &amp;quot;5:FHEMduino_PT2262&amp;quot;   =&amp;gt; &amp;quot;^(?-i)IR.*\$&amp;quot;,&lt;br /&gt;
    ....&lt;br /&gt;
    &amp;quot;13:IT&amp;quot;                =&amp;gt; &amp;quot;^(?-i)i......\$&amp;quot;,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe dazu Forumsbeitrag: {{Link2Forum|Topic=33422}}&lt;br /&gt;
}}&lt;br /&gt;
Die Match-Liste ordnet eine Nachrichtensyntax (regulärer Ausdruck) einem Modulnamen zu und wird in einem physikalischen Modul gesetzt. Sollte eine Nachricht vom physikalischen Gerät empfangen werden, die durch kein geladenes Modul verarbeitet werden kann ([[DevelopmentModuleAPI#Dispatch|Dispatch()]] prüft nur alle bisher geladenen Module aus der [[#Die Client-Liste|Client-Liste]]), so wird über die Match-Liste geprüft, welches Modul diese Nachricht verarbeiten kann. Dieses Modul wird anschließend geladen und die Nachricht durch dieses direkt durch Aufruf der [[#X_Parse|Parse]]-Funktion verarbeitet. In dieser Liste findet mittels regulärem Ausdruck eine Zuordnung der Nachrichtenstruktur zum verarbeitenden logischen Modul statt.&lt;br /&gt;
&lt;br /&gt;
Diese Liste wird ausschließlich in der [[DevelopmentModuleAPI#Dispatch|Dispatch()]]-Funktion verwendet. Sollte keine passendes Modul, welches bereits geladen ist, zur Verarbeitung einer Nachricht gefunden werden, so wird mithilfe der Match-Liste aufgrund der vorliegenden Nachricht das entsprechende Modul ermittelt. Dieses Modul wird dann direkt geladen und die Nachricht wird via [[#X_Parse|Parse]]-Funktion verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Die Match-Liste ist eine Zuordnung von einem Sortierpräfix + Modulname zu einem regulären Ausdruck:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;1:FS20&amp;quot;  =&amp;gt; &amp;quot;^81..(04|0c)..0101a001&amp;quot;,&lt;br /&gt;
    &amp;quot;2:KS300&amp;quot; =&amp;gt; &amp;quot;^810d04..4027a001&amp;quot;,&lt;br /&gt;
    &amp;quot;3:FHT&amp;quot;   =&amp;gt; &amp;quot;^81..(04|09|0d)..(0909a001|83098301|c409c401)..&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Sortierpräfix (&amp;lt;code&amp;gt;&amp;lt;u&amp;gt;1:&amp;lt;/u&amp;gt;&amp;lt;font color=&amp;quot;grey&amp;quot;&amp;gt;FS20&amp;lt;/font&amp;gt;&amp;lt;/code&amp;gt;) dient als Sortierhilfe um so die Reihenfolge der Prüfung festzulegen. Bei der Prüfung wird die Match-Liste mittels sort() nach dem Schlüssel (Sortierpräfix + Modulname) sortiert und die regulären Ausdrücke werden dann nacheinander getestet. Daher sollten die präzisesten Ausdrücke immer zuerst getestet werden, sofern es weniger präzise Ausdrücke in der Match-Liste gibt. Dabei ist zu beachten, dass der Sortierpräfix nicht nach numerischen Regeln sortiert wird, sondern zeichenbasierend.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird die Match-Liste in der [[#X_Initialize|Initialize]]-Funktion im Modul-Hash gesetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Initialize($)&lt;br /&gt;
{&lt;br /&gt;
   my ($hash) = @_;&lt;br /&gt;
&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
   $hash-&amp;gt;{MatchList} = { &amp;quot;1:FS20&amp;quot;      =&amp;gt; &amp;quot;^81..(04|0c)..0101a001&amp;quot;,&lt;br /&gt;
                          &amp;quot;2:KS300&amp;quot;     =&amp;gt; &amp;quot;^810d04..4027a001&amp;quot;,&lt;br /&gt;
                          &amp;quot;3:FHT&amp;quot;       =&amp;gt; &amp;quot;^81..(04|09|0d)..(0909a001|83098301|c409c401)..&amp;quot; };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man kann die Match-Liste, ähnlich wie bei der Client-Liste, auch pro physikalisches Gerät setzen. Dabei hat auch hier die Match-Liste eines Gerätes immer Vorrang vor der Match-Liste aus dem Modul-Hash:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Define($$)&lt;br /&gt;
{&lt;br /&gt;
   my ($hash, $def) = @_;&lt;br /&gt;
&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
   $hash-&amp;gt;{MatchList} = { &amp;quot;1:CUL_HM&amp;quot; =&amp;gt; &amp;quot;^A....................&amp;quot; };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Der Match-Ausdruck ===&lt;br /&gt;
&lt;br /&gt;
Ein Match-Ausdruck wird in einem logischen Modul gesetzt und dient der Prüfung, ob eine Nachricht durch das eigene Modul via [[#X_Parse|Parse]]-Funktion verarbeitet werden kann. Es handelt sich hierbei um einen einzelnen regulären Ausdruck, den FHEM innerhalb der [[DevelopmentModuleAPI#Dispatch|Dispatch()]]-Funktion prüft. Nur wenn eine Nachricht via Dispatch() auf diesen Audruck matcht, wird die Parse-Funktion des eigenen Moduls aufgerufen um die Nachricht zu verarbeiten. &lt;br /&gt;
&lt;br /&gt;
Der Hintergrund, warum man den Aufruf mit einem solchen Ausdruck vorher abprüft, liegt in der Möglichkeit, dass ein physikalisches Modul mehrere unterschiedliche logische Module ansprechen kann. So kann FHEM jedes geladene Modul durch diesen Match-Ausdruck prüfen, ob es diese Nachricht verarbeiten kann. Erst, wenn alle geladenen Module, aufgrund einer Prüfung des Ausdrucks, die Nachricht nicht verarbeiten können, wird via [[#Die_Match-Liste|Match-Liste]] ermittelt, welches Modul geladen werden muss um die Nachricht zu verarbeiten. &lt;br /&gt;
&lt;br /&gt;
Der Match-Ausdruck wird in der [[#X_Initialize|Initialize]]-Funktion zur Verfügung gestellt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Initialize($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
&lt;br /&gt;
	...&lt;br /&gt;
	&lt;br /&gt;
	# Dieses Modul verarbeitet FS20 Nachrichten&lt;br /&gt;
	$hash-&amp;gt;{Match} = &amp;quot;^81..(04|0c)..0101a001&amp;quot;; &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Die vollständige Implementierung ===&lt;br /&gt;
&lt;br /&gt;
Hier nun eine Zusammenfassung beim zweistufigen Modulkonzept in der jeweiligen Stufe implementiert werden muss, damit die Kommunikation funktioniert.&lt;br /&gt;
&lt;br /&gt;
==== physisches Modul ====&lt;br /&gt;
&lt;br /&gt;
Das physische Modul, welches als Kommunikationsbrücke zwischen der Hardware und logischen Modulen fungieren wird, sollte mindestens folgende Funktionen implementieren:&lt;br /&gt;
&lt;br /&gt;
* [[#X_Initialize|Initialize]]-Funktion - Zum Registrieren des Moduls in FHEM.&lt;br /&gt;
* [[#X_Define|Define]]-Funktion - Zum öffnen der Datenverbindung zur Hardware (IP-Adresse/serielle Schnittstelle/...).&lt;br /&gt;
* [[#X_Read|Read]]-Funktion - Zum Lesen von Daten, welche die Hardware übermittelt.&lt;br /&gt;
* [[#X_Read|Ready]]-Funktion - Zum Wiederaufbau der Verbindung bei Verbindungsabbruch, bzw. Prüfung auf lesbare Daten bei serieller Schnittstelle unter Windows.&lt;br /&gt;
* [[#X_Write|Write]]-Funktion - Zum Senden von Daten, welche logische Module via [[DevelopmentModuleAPI#IOWrite|IOWrite()]] an die Hardware übertragen möchten.&lt;br /&gt;
* [[#X_Undef|Undef]]-Funktion - Schließen der Verbindung zur Hardware beim Löschen via &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;rereadcfg&amp;lt;/code&amp;gt;.&lt;br /&gt;
* [[#X_Shutdown|Shutdown]]-Funktion - Schließen der Verbindung zur Hardware beim Stopp von FHEM via &amp;lt;code&amp;gt;shutdown&amp;lt;/code&amp;gt;.&lt;br /&gt;
* [[#X_DelayedShutdown | DelayedShutdown]]-Funktion - Verzögertes beenden zum Schließen der Verbindung zur Hardware beim Stopp von FHEM via &amp;lt;code&amp;gt;shutdown&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen in der [[#X_Initialize|Initialize]]-Funktion folgende Daten bereitgestellt werden:&lt;br /&gt;
&lt;br /&gt;
* [[#Die_Client-Liste|Client-Liste]] - Auflistung aller logischen Module, die über dieses Modul kommunizieren können&lt;br /&gt;
* [[#Die_Match-Liste|Match-Liste]] - Zuordnung von Nachrichtensyntax zu Modul zwecks Autoload-Funktionalität.&lt;br /&gt;
&lt;br /&gt;
==== logisches Modul ====&lt;br /&gt;
&lt;br /&gt;
Das logische Modul, bildet ein einzelnes Gerät ab, über das mit einem physikalisches Modul kommuniziert werden kann. Es sollte mindestens folgende Funktionen implementieren:&lt;br /&gt;
&lt;br /&gt;
* [[#X_Initialize|Initialize]]-Funktion - Zum Registrieren des Moduls in FHEM.&lt;br /&gt;
* [[#X_Define|Define]]-Funktion - Speichern des Definition Pointers (siehe [[#X_Parse|Parse-Funktion]])&lt;br /&gt;
* [[#X_Parse|Parse]]-Funktion - Zum Lesen von Daten, welche die Hardware übermittelt.&lt;br /&gt;
* [[#X_Undef|Undef]]-Funktion - Löschen des Definition Pointers beim Löschen via &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;rereadcfg&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen in der [[#X_Initialize|Initialize]]-Funktion folgende Daten bereitgestellt werden:&lt;br /&gt;
&lt;br /&gt;
* [[#Der_Match-Ausdruck|Match-Ausdruck]] - Prüfausdruck, ob eine Nachricht durch dieses Modul verarbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
=== Kommunikation von der Hardware bis zu den logischen Modulen ===&lt;br /&gt;
&lt;br /&gt;
Die Gerätedefinition des physischen Moduls öffnet eine Verbindung zur Hardware (z.B. via [[DevIo]]). Die [[#X_Read|Read]]-Funktion wird bei anstehenden Daten aus der Hauptschleife von fhem.pl aufgerufen.&lt;br /&gt;
&lt;br /&gt;
Die Read-Funktion stellt dabei sicher, dass die Daten&lt;br /&gt;
* komplett (in der Regel über einen internen Puffer in &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;) und&lt;br /&gt;
* korrekt (z.B. via Prüfung mittels regulärem Ausdruck)&lt;br /&gt;
sind und ruft die globale Funktion [[DevelopmentModuleAPI#Dispatch|Dispatch()]] mit einer kompletten Nachricht auf.&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() prüft alle geladenen Module aus der [[#Die_Client-Liste|Client-Liste]] des physikalischen Moduls nach möglichen logischen Modulen zur Verarbeitung. Alle zum Zeitpunkt geladenen Module, die in der Client-Liste aufgeführt sind, werden über den [[#Der_Match-Ausdruck|Match-Ausdruck]] geprüft, ob sie mit der Nachricht etwas anfangen können. Sollte bei einem logischen Modul der Match-Ausdruck passen, so wird die entsprechende [[#X_Parse|Parse]]-Funktion des logischen Moduls aufgerufen. Sofern keine passendes Modul gefunden wurde, um die Nachricht zu verarbeiten, wird in der [[#Die_Match-Liste|Match-Liste]] im Geräte- bzw. Modul-Hash der physischen Gerätedefinition nach dem passenden Modul gesucht. Sollte es darin ein Modul geben, was diese Art von Nachricht verarbeiten kann, so wird versucht dieses Modul zu laden um nun die Nachricht via Parse-Funktion zu verarbeiten. Es erfolgt in diesem Fall keine Vorprüfung durch den Match-Ausdruck.&lt;br /&gt;
&lt;br /&gt;
Durch Dispatch() wird nun die [[#X_Parse|Parse]]-Funktion des gefundenen logischen Moduls aufgerufen. Diese&lt;br /&gt;
* interpretiert die übergebene Nachricht,&lt;br /&gt;
* versucht eine existierende Gerätedefinition in FHEM zu finden (z.B. mittels Definition Pointer), für welche die Nachricht addressiert ist,&lt;br /&gt;
* setzt alle [[#Readings|Readings]] für die gefundene Gerätedefinition via [[DevelopmentModuleAPI#Readings_.2F_Events|readings*update]]()-Funktionen,&lt;br /&gt;
* gibt den Namen der logischen Definition zurück, welche die Nachricht verarbeitet hat.&lt;br /&gt;
&lt;br /&gt;
Sollte keine passende Gerätedefinition für die entsprechende Nachricht existieren (Adresse/ID/Kanal/...), wird der Gerätename &amp;quot;UNDEFINED&amp;quot; inkl. einem passenden &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Statement zurückgegeben, um die Definition durch [[autocreate]] erzeugen zu lassen.&lt;br /&gt;
&lt;br /&gt;
Es findet während der Verarbeitung einer Nachricht durch Dispatch()/Parse-Funktion keine sofortige Eventverarbeitung (via [[DevelopmentModuleAPI#Dispatch|DoTrigger()]]) statt, wenn die [[DevelopmentModuleAPI#Readings_.2F_Events|readings*update]]()-Funktionen verwendet werden.&lt;br /&gt;
(Im Gegensatz zum direkten Aufrufen der readings*update Funktionen ohne vorhergehendes Dispatch() )&lt;br /&gt;
&lt;br /&gt;
Die Funktion Dispatch() triggert das Event-Handling für das von der Parse-Funktion zurückgegebene logische Device selbstständig nach Abschluss der Parse-Funktion.&lt;br /&gt;
&lt;br /&gt;
Optional führt die Funktion Dispatch() eine Überprüfung auf Nachrichtenduplikate beim Einsatz von mehreren IO-Geräten durch. Dazu wird eine implementierte [[#X_Fingerprint|Fingerprint]]-Funktion im physischen oder logischen Modul benötigt. Sollte der Fingerprint einer Nachricht innerhalb einer bestimmten Zeit (globales Attribut &amp;lt;code&amp;gt;dupTimeout&amp;lt;/code&amp;gt;, standardmäßig 500ms) bereits empfangen worden sein, so wird die Nachricht verworfen. Dies ist insbesondere bei funkbasierter Hardware notwendig, wenn mehrere Empfänger die selbe Nachricht empfangen.&lt;br /&gt;
&lt;br /&gt;
=== Kommunikation von den logischen Modulen bis zur Hardware ===&lt;br /&gt;
&lt;br /&gt;
Um von einem logischen Modul eine Nachricht an die Hardware senden zu können, muss zunächst im logischen Gerät ein passenden IO-Gerät ausgewählt sein. Dazu muss die Funktion [[DevelopmentModuleAPI#AssignIoPort|AssignIoPort()]] ein entsprechendes IO-Gerät auswählen und in &amp;lt;code&amp;gt;$hash-&amp;gt;{IODev}&amp;lt;/code&amp;gt; setzen. Dieser Aufruf wird üblicherweise in der [[#X_Define|Define]]-Funktion des logischen Moduls ausgeführt. Erst, wenn ein IO-Gerät ausgewählt wurde, können Daten über das physikalische Gerät an die Hardware übermittelt werden.&lt;br /&gt;
&lt;br /&gt;
Zum Senden von Daten ruft das logische Modul die Funktion [[DevelopmentModuleAPI#IOWrite|IOWrite()]] samt Daten auf. Diese ruft für das entsprechende IO-Gerät die [[#X_Write|Write]]-Funktion auf und übergibt die Daten zum Schreiben an das physikalische Modul. Die Write-Funktion kümmert sich nun um die Übertragung der Daten an die Hardware. &lt;br /&gt;
&lt;br /&gt;
Keine direkten Zugriffe zwischen dem logischen und dem physischen Gerät gibt (d.h. keine direkten Aufrufe von Funktionen, kein direktes Überprüfen von &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt;-Inhalten, ...), so können die Module hintereinander geschaltet werden (z.B. für Routerfunktionen wie bei der [[RFR_CUL|RFR]]-Funktionalität) oder mittels [[FHEM2FHEM]] im RAW-Modus zwei FHEM-Installationen verbunden werden und die logischen Geräte können dennoch kommunizieren.&lt;br /&gt;
&lt;br /&gt;
=== Automatisches Anlegen von logischen Gerätedefinitionen (autocreate) ===&lt;br /&gt;
&lt;br /&gt;
Das logische Modul kann im Rahmen der [[#X_Parse|Parse]]-Funktion eine neue Gerätedefinition anlegen, sofern eine passende Definition nicht existieren sollte. Die Parse-Funktion gibt generell den Namen der logischen Gerätedefinition zurück, für welche die Nachricht verarbeitet wurde. Sollte keine passende Definition gefunden werden, so muss die Parse-Funktion folgenden Rückgabewert liefern (zusammenhängende Zeichenkette):&lt;br /&gt;
&lt;br /&gt;
 UNDEFINED &#039;&#039;&amp;amp;lt;Namensvorschlag&amp;amp;gt;&#039;&#039; &#039;&#039;&amp;amp;lt;Modulname&amp;amp;gt;&#039;&#039; &#039;&#039;&amp;amp;lt;Define-Parameter...&amp;amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sollte also bspw. im Rahmen der Parse-Funktion zu Modul X eine Nachricht nicht einer existierenden Gerätedefinition zugeordnet werden können, so muss ein Namensvorschlag erstellt werden der eine eindeutige Komponente wie bspw. eine Adresse/ID/Kanal-Nr enthält. In der Regel wird hier immer der Modulname zusammen mit der eindeutigen Komponente, durch einen Unterstrich getrennt, verwendet (Bsp: &amp;lt;code&amp;gt;X_4834&amp;lt;/code&amp;gt;). Der Modulname ist in der Regel immer der, des eigenen Moduls. In besonderen Fällen kann man hier auch einen abweichenden Modulnamen angeben. Dies wird bspw. bei den [[PanStamp#FHEM-Module.2FDevice_Definition_Files|SWAP-Modulen]] eingesetzt. Als Define-Parameter müssen alle notwendigen Parameter angegeben werden, die beim Aufruf des &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Befehls notwendig sind, damit eine neu angelegte Gerätedefinition Nachrichten zu dieser eindeutigen Adresse Daten verarbeitet. Dazu muss mind. die eindeutige Adresse mitgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel für FS20:&lt;br /&gt;
&lt;br /&gt;
 UNDEFINED FS20_0ae42f8 FS20 0ae42 f8&lt;br /&gt;
&lt;br /&gt;
Sobald [[DevelopmentModuleAPI#Dispatch|Dispatch()]] einen solchen Rückgabewert von einer [[#X_Parse|Parse]]-Funktion erhält, wird diese Zeichenkette so wie sie ist via [[DevelopmentModuleAPI#DoTrigger|DoTrigger()]] als Event für die Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; getriggert.&lt;br /&gt;
&lt;br /&gt;
Sofern der Nutzer das Modul [[autocreate]] verwendet (definiert hat), kümmert sich dieses nun um das Anlegen einer entsprechenden Gerätedefinition. Es lauscht dabei auf generierte Events der Definition &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; via [[#X_Notify|Notify]]-Funktion. Der Nutzer kann dabei das Verhalten von autocreate durch entsprechende Parameter beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Das Modul, für welches autocreate eine neue Definition anlegen möchte, kann das Verhalten durch entsprechende Parameter im Modul-Hash beeinflussen. Dabei gilt, dass gesetzte Attribute durch den Nutzer generell Vorrang haben. Die entsprechenden Parameter werden dabei im Rahmen der [[#X_Initialize|Initialize]]-Funktion im Modul-Hash gesetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub X_Initialize($)&lt;br /&gt;
{&lt;br /&gt;
	my ($hash) = @_;&lt;br /&gt;
 &lt;br /&gt;
	...&lt;br /&gt;
 &lt;br /&gt;
	$hash-&amp;gt;{AutoCreate} = {&amp;quot;X_.*&amp;quot;  =&amp;gt; { ATTR   =&amp;gt; &amp;quot;event-on-change-reading:.* event-min-interval:.*:300&amp;quot;,&lt;br /&gt;
	                                    FILTER =&amp;gt; &amp;quot;%NAME&amp;quot;,&lt;br /&gt;
	                                    GPLOT  =&amp;gt; &amp;quot;temp4hum4:Temp/Hum,&amp;quot;,&lt;br /&gt;
	                                    autocreateThreshold =&amp;gt; &amp;quot;2:140&amp;quot;&lt;br /&gt;
					  }&lt;br /&gt;
	                      };&lt;br /&gt;
			    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei wird unterhalb von &amp;lt;code&amp;gt;$hash-&amp;gt;{AutoCreate}&amp;lt;/code&amp;gt; eine Liste angelegt, wo einem regulären Ausdruck für einen anzulegenden Definitionsnamen entsprechende Optionen zugeordnet werden. Sobald durch autocreate eine Gerätedefintion angelegt wird, auf den ein hier gelisteter Ausdruck matcht, so werden die zugeordneten Optionen berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Hier eine Auflistung aller möglichen Optionen und ihrer Bedeutung:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Optionsname !! Beispiel !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;ATTR&amp;lt;/code&amp;gt;|| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; |  &amp;lt;code&amp;gt;&amp;quot;event-on-change-reading:.* event-min-interval:.*:300&amp;quot;&amp;lt;/code&amp;gt; || Eine Auflistung von Attributen, die nach dem Anlegen einer Definition zusätzlich gesetzt werden. Es handelt sich hierbei um eine Leerzeichen-separierte Liste von Doppelpunkt-getrennten Tupels mit Attributname und -wert.&lt;br /&gt;
&lt;br /&gt;
Für das dargestellte Beispiel bedeutet dies, dass nach dem Anlegen der Definition folgende FHEM-Befehle zusätzlich ausgeführt werden:&lt;br /&gt;
&lt;br /&gt;
 attr &#039;&#039;&amp;amp;lt;Name&amp;amp;gt;&#039;&#039; event-on-change-reading .*&lt;br /&gt;
 attr &#039;&#039;&amp;amp;lt;Name&amp;amp;gt;&#039;&#039; event-min-interval .*:300&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;FILTER&amp;lt;/code&amp;gt; || style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; |  &amp;lt;code&amp;gt;&amp;quot;%NAME&amp;quot;&amp;lt;/code&amp;gt;|| Sofern in der autocreate-Definiton das Attribut &amp;lt;code&amp;gt;filelog&amp;lt;/code&amp;gt; entsprechend durch den Nutzer gesetzt ist, wird eine zugehörige FileLog-Definition angelegt. Diese Option setzt den dabei benutzten Filter-Regexp, der beim Anlegen der FileLog-Definition gesetzt wird. &lt;br /&gt;
&lt;br /&gt;
Dabei werden folgende Platzhalter durch die entsprechenden Werte der neu angelegten Gerätedefinition ersetzt:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;%NAME&amp;lt;/code&amp;gt; - wird ersetzt durch den Definitionsnamen&lt;br /&gt;
* &amp;lt;code&amp;gt;%TYPE&amp;lt;/code&amp;gt; - wird ersetzt durch den Modulnamen&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; |  &amp;lt;code&amp;gt;GPLOT&amp;lt;/code&amp;gt; || style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;&amp;quot;temp4hum4:Temp/Hum,&amp;quot;&amp;lt;/code&amp;gt; || Sofern eine FileLog-Definition angelegt wurde, kann man weiterführend dazu eine passende SVG-Definition erzeugen um Daten aus dem erzeugten FileLog zu visualisieren. Ein typischer Fall sind hierbei Temperatursensoren, wo es sinnvoll sein kann, einen passenden SVG-Plot mit Temperatur/Luftfeuchtigkeit direkt anzulegen.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich hierbei um eine kommaseparierte Auflistung von gplot-Dateinamen und optionalen Label-Texten durch einen Doppelpunkt getrennt. Im genannten Beispiel entspricht &amp;lt;code&amp;gt;temp4hum4&amp;lt;/code&amp;gt; der zu verwendenden GnuPlot-Datei und &amp;lt;code&amp;gt;Temp/Hum&amp;lt;/code&amp;gt; dem zu verwendenden Label ([[SVG]] Attribut &amp;lt;code&amp;gt;label&amp;lt;/code&amp;gt;). Das Label wird auch durch FileLog verwendet als Link-Text zum entsprechenden SVG Plot. Alternativ kann auch nur die entsprechende GnuPlot-Datei anegeben werden ohne Label. Für jede angegebene GnuPlot-Datei wird anschließend eine entsprechende SVG-Definition erzeugt mit der vorher erzeugten FileLog-Definition als Datenquelle.&lt;br /&gt;
&lt;br /&gt;
Der gesamte Inhalt der &amp;lt;code&amp;gt;GPLOT&amp;lt;/code&amp;gt;-Option wird beim Anlegen einer FileLog-Definition dem Attribut &amp;lt;code&amp;gt;logtype&amp;lt;/code&amp;gt; als Wert plus dem Text &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt; zugewiesen. Daher muss der Inhalt der Option &amp;lt;code&amp;gt;GPLOT&amp;lt;/code&amp;gt; immer mit einem Komma enden. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;autocreateThreshold&amp;lt;/code&amp;gt; || style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;&amp;quot;2:10&amp;quot;&amp;lt;/code&amp;gt; || Definiert, wie viele Aufrufe (im Bsp: &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt;) von autocreate innerhalb welcher Zeit (im Bsp: &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt; Sek.) stattfinden müssen, bevor die Gerätedefinition tatsächlich durch autocreate angelegt wird. Dadurch kann das ungewollte Anlegen von Geräten verhindert werden die tatsächlich nicht in Echt existieren. Aufgrund von Funkstörungen kann es durchaus zum ungewollten Anlegen einer Definition kommen. Diese Funktion lässt eine Definition erst zu wenn innerhalb einer vorgegeben Zeit eine Mindestzahl an Nachrichten eintrifft.&lt;br /&gt;
&lt;br /&gt;
Die erste Zahl stellt dabei die Mindestanzahl an Nachrichten dar. Die Zweite Zahl stellt die Zeit in Sekunden dar, in der die Mindestanzahl an Nachrichten erreicht werden muss um eine entsprechende Gerätedefinition anzulegen. &lt;br /&gt;
&lt;br /&gt;
Sofern diese Option nicht gesetzt ist, wird standardmäßig &amp;lt;code&amp;gt;2:60&amp;lt;/code&amp;gt; verwendet.&lt;br /&gt;
&lt;br /&gt;
Diese Option kann durch den Anwender über das Attribut &amp;lt;code&amp;gt;autocreateThreshold&amp;lt;/code&amp;gt; übersteuert werden.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; | &amp;lt;code&amp;gt;noAutocreatedFilelog&amp;lt;/code&amp;gt;|| style=&amp;quot;vertical-align:top; white-space: nowrap;&amp;quot; |  &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;|| Flag. Sofern gesetzt, wird keine FileLog- und ggf. SVG-Definition erzeugt. Selbst wenn der Nutzer durch entsprechende Attribute das Anlegen wünscht. Diese Option ist sinnvoll für Module bzw. Geräte die keine Readings erzeugen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ergänzende Hinweise ==&lt;br /&gt;
Die Wahl der vorangestellten Nummer für den Dateinamen eines neuen Moduls hat keine Bedeutung mehr, es sei denn die Nummer ist 99. Module, die mit 99_ beginnen, werden von FHEM automatisch geladen. Module mit einer anderen Nummer nur wenn ein &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;-Befehl dafür sorgt, dass das Modul geladen wird.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Modul Initialisierungsdaten benötigt, sollten diese im Modul selbst enthalten sein. Eine zusätzliche Datei oder sogar ein Unterverzeichnis mit mehreren Dateien ist bei FHEM nicht üblich und sollte bei Modulen, die mit FHEM ausgeliefert werden nur in Rücksprache mit Rudolf König angelegt werden, da sie sonst bei einem Update nicht verteilt werden.&lt;br /&gt;
&lt;br /&gt;
== Weitere Informationen ==&lt;br /&gt;
Wenn man weitere Details wissen möchte, ist ein erster sinnvoller Schritt ein Blick in die Datei fhem.pl. Dort sieht man im Perl-Code wie die Module aufgerufen werden, was vorher passiert und was danach. Am Anfang der Datei (ca. ab Zeile 130) findet man beispielsweise eine Liste der globalen Variablen, die den Modulen zur Verfügung stehen sowie Details zu den wichtigen Hashes %modules und %defs. Wer mit Perl noch nicht so gut klar kommt, dem hilft eventuell ein Blick auf die Perldoc Website[http://perldoc.perl.org/] oder in das Perl-Buch seiner Wahl. Auch die FHEM {{Link2CmdRef}} sollte nicht unterschätzt werden. Es stehen oft mehr interessante Details auch für Modulentwickler darin als man zunächst vermuten könnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Hello World&amp;quot; Beispiel ==&lt;br /&gt;
&lt;br /&gt;
98_Hello.pm&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
package main;&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
&lt;br /&gt;
my %Hello_gets = (&lt;br /&gt;
	&amp;quot;whatyouwant&amp;quot;	=&amp;gt; &amp;quot;can&#039;t&amp;quot;,&lt;br /&gt;
	&amp;quot;whatyouneed&amp;quot;	=&amp;gt; &amp;quot;try sometimes&amp;quot;,&lt;br /&gt;
	&amp;quot;satisfaction&amp;quot;  =&amp;gt; &amp;quot;no&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
sub Hello_Initialize($) {&lt;br /&gt;
    my ($hash) = @_;&lt;br /&gt;
&lt;br /&gt;
    $hash-&amp;gt;{DefFn}      = &#039;Hello_Define&#039;;&lt;br /&gt;
    $hash-&amp;gt;{UndefFn}    = &#039;Hello_Undef&#039;;&lt;br /&gt;
    $hash-&amp;gt;{SetFn}      = &#039;Hello_Set&#039;;&lt;br /&gt;
    $hash-&amp;gt;{GetFn}      = &#039;Hello_Get&#039;;&lt;br /&gt;
    $hash-&amp;gt;{AttrFn}     = &#039;Hello_Attr&#039;;&lt;br /&gt;
    $hash-&amp;gt;{ReadFn}     = &#039;Hello_Read&#039;;&lt;br /&gt;
&lt;br /&gt;
    $hash-&amp;gt;{AttrList} =&lt;br /&gt;
          &amp;quot;formal:yes,no &amp;quot;&lt;br /&gt;
        . $readingFnAttributes;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub Hello_Define($$) {&lt;br /&gt;
    my ($hash, $def) = @_;&lt;br /&gt;
    my @param = split(&#039;[ \t]+&#039;, $def);&lt;br /&gt;
    &lt;br /&gt;
    if(int(@param) &amp;lt; 3) {&lt;br /&gt;
        return &amp;quot;too few parameters: define &amp;lt;name&amp;gt; Hello &amp;lt;greet&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    my $hash-&amp;gt;{name}  = $param[0];&lt;br /&gt;
    my $hash-&amp;gt;{greet} = $param[2];&lt;br /&gt;
    &lt;br /&gt;
    return undef;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub Hello_Undef($$) {&lt;br /&gt;
    my ($hash, $arg) = @_; &lt;br /&gt;
    # nothing to do&lt;br /&gt;
    return undef;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub Hello_Get($@) {&lt;br /&gt;
	my ($hash, @param) = @_;&lt;br /&gt;
	&lt;br /&gt;
	return &#039;&amp;quot;get Hello&amp;quot; needs at least one argument&#039; if (int(@param) &amp;lt; 2);&lt;br /&gt;
	&lt;br /&gt;
	my $name = shift @param;&lt;br /&gt;
	my $opt = shift @param;&lt;br /&gt;
	if(!$Hello_gets{$opt}) {&lt;br /&gt;
		my @cList = keys %Hello_gets;&lt;br /&gt;
		return &amp;quot;Unknown argument $opt, choose one of &amp;quot; . join(&amp;quot; &amp;quot;, @cList);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if($attr{$name}{formal} eq &#039;yes&#039;) {&lt;br /&gt;
	    return $Hello_gets{$opt}.&#039;, sir&#039;;&lt;br /&gt;
    }&lt;br /&gt;
	return $Hello_gets{$opt};&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub Hello_Set($@) {&lt;br /&gt;
	my ($hash, @param) = @_;&lt;br /&gt;
	&lt;br /&gt;
	return &#039;&amp;quot;set Hello&amp;quot; needs at least one argument&#039; if (int(@param) &amp;lt; 2);&lt;br /&gt;
	&lt;br /&gt;
	my $name = shift @param;&lt;br /&gt;
	my $opt = shift @param;&lt;br /&gt;
	my $value = join(&amp;quot;&amp;quot;, @param);&lt;br /&gt;
	&lt;br /&gt;
	if(!defined($Hello_gets{$opt})) {&lt;br /&gt;
		my @cList = keys %Hello_gets;&lt;br /&gt;
		return &amp;quot;Unknown argument $opt, choose one of &amp;quot; . join(&amp;quot; &amp;quot;, @cList);&lt;br /&gt;
	}&lt;br /&gt;
    $hash-&amp;gt;{STATE} = $Hello_gets{$opt} = $value;&lt;br /&gt;
    &lt;br /&gt;
	return &amp;quot;$opt set to $value. Try to get it.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sub Hello_Attr(@) {&lt;br /&gt;
	my ($cmd,$name,$attr_name,$attr_value) = @_;&lt;br /&gt;
	if($cmd eq &amp;quot;set&amp;quot;) {&lt;br /&gt;
        if($attr_name eq &amp;quot;formal&amp;quot;) {&lt;br /&gt;
			if($attr_value !~ /^yes|no$/) {&lt;br /&gt;
			    my $err = &amp;quot;Invalid argument $attr_value to $attr_name. Must be yes or no.&amp;quot;;&lt;br /&gt;
			    Log 3, &amp;quot;Hello: &amp;quot;.$err;&lt;br /&gt;
			    return $err;&lt;br /&gt;
			}&lt;br /&gt;
		} else {&lt;br /&gt;
		    return &amp;quot;Unknown attr $attr_name&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return undef;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
1;&lt;br /&gt;
&lt;br /&gt;
=pod&lt;br /&gt;
=begin html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;a name=&amp;quot;Hello&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Hello&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
    &amp;lt;i&amp;gt;Hello&amp;lt;/i&amp;gt; implements the classical &amp;quot;Hello World&amp;quot; as a starting point for module development. &lt;br /&gt;
    You may want to copy 98_Hello.pm to start implementing a module of your very own. See &lt;br /&gt;
    &amp;lt;a href=&amp;quot;http://wiki.fhem.de/wiki/DevelopmentModuleIntro&amp;quot;&amp;gt;DevelopmentModuleIntro&amp;lt;/a&amp;gt; for an &lt;br /&gt;
    in-depth instruction to your first module.&lt;br /&gt;
    &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
    &amp;lt;a name=&amp;quot;Hellodefine&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Define&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;code&amp;gt;define &amp;amp;lt;name&amp;amp;gt; Hello &amp;amp;lt;greet&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
        &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        Example: &amp;lt;code&amp;gt;define HELLO Hello TurnUrRadioOn&amp;lt;/code&amp;gt;&lt;br /&gt;
        &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        The &amp;quot;greet&amp;quot; parameter has no further meaning, it just demonstrates&lt;br /&gt;
        how to set a so called &amp;quot;Internal&amp;quot; value. See &amp;lt;a href=&amp;quot;http://fhem.de/commandref.html#define&amp;quot;&amp;gt;commandref#define&amp;lt;/a&amp;gt; &lt;br /&gt;
        for more info about the define command.&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;br&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;a name=&amp;quot;Helloset&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Set&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;code&amp;gt;set &amp;amp;lt;name&amp;amp;gt; &amp;amp;lt;option&amp;amp;gt; &amp;amp;lt;value&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
        &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        You can &amp;lt;i&amp;gt;set&amp;lt;/i&amp;gt; any value to any of the following options. They&#039;re just there to &lt;br /&gt;
        &amp;lt;i&amp;gt;get&amp;lt;/i&amp;gt; them. See &amp;lt;a href=&amp;quot;http://fhem.de/commandref.html#set&amp;quot;&amp;gt;commandref#set&amp;lt;/a&amp;gt; &lt;br /&gt;
        for more info about the set command.&lt;br /&gt;
        &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        Options:&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
              &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;satisfaction&amp;lt;/i&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
                  Defaults to &amp;quot;no&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
              &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;whatyouwant&amp;lt;/i&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
                  Defaults to &amp;quot;can&#039;t&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
              &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;whatyouneed&amp;lt;/i&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
                  Defaults to &amp;quot;try sometimes&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;a name=&amp;quot;Helloget&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Get&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;code&amp;gt;get &amp;amp;lt;name&amp;amp;gt; &amp;amp;lt;option&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
        &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        You can &amp;lt;i&amp;gt;get&amp;lt;/i&amp;gt; the value of any of the options described in &lt;br /&gt;
        &amp;lt;a href=&amp;quot;#Helloset&amp;quot;&amp;gt;paragraph &amp;quot;Set&amp;quot; above&amp;lt;/a&amp;gt;. See &lt;br /&gt;
        &amp;lt;a href=&amp;quot;http://fhem.de/commandref.html#get&amp;quot;&amp;gt;commandref#get&amp;lt;/a&amp;gt; for more info about &lt;br /&gt;
        the get command.&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;br&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;a name=&amp;quot;Helloattr&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Attributes&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;code&amp;gt;attr &amp;amp;lt;name&amp;amp;gt; &amp;amp;lt;attribute&amp;amp;gt; &amp;amp;lt;value&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
        &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        See &amp;lt;a href=&amp;quot;http://fhem.de/commandref.html#attr&amp;quot;&amp;gt;commandref#attr&amp;lt;/a&amp;gt; for more info about &lt;br /&gt;
        the attr command.&lt;br /&gt;
        &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        Attributes:&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
            &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;formal&amp;lt;/i&amp;gt; no|yes&amp;lt;br&amp;gt;&lt;br /&gt;
                When you set formal to &amp;quot;yes&amp;quot;, all output of &amp;lt;i&amp;gt;get&amp;lt;/i&amp;gt; will be in a&lt;br /&gt;
                more formal language. Default is &amp;quot;no&amp;quot;.&lt;br /&gt;
            &amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=end html&lt;br /&gt;
&lt;br /&gt;
=cut&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der HTML-Code zwischen den Tags &amp;lt;code&amp;gt;=pod&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;=cut&amp;lt;/code&amp;gt; dient zur Generierung der commandref.html. Der HTML-Inhalt wird automatisch beim Verteilen des Moduls im Rahmen des Update-Mechanismus aus jedem Modul extrahiert und daraus die Commandref in verschiedenen Sprachen erstellt. Eine detaillierte Beschreibung wie ein Commandref-Abschnitt in einem Modul definiert wird, siehe: [[Guidelines zur Dokumentation]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=HttpUtils&amp;diff=33262</id>
		<title>HttpUtils</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=HttpUtils&amp;diff=33262"/>
		<updated>2020-05-22T12:04:54Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Nutzlose Prototypen entfernt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Hilfsfunktionen für HTTP-Zugriffe&lt;br /&gt;
|ModType=u&lt;br /&gt;
|ModForumArea=Automatisierung&lt;br /&gt;
|ModTechName=HttpUtils.pm&lt;br /&gt;
|ModOwner=rudolfkoenig ({{Link2FU|8|Forum}} / [[Benutzer Diskussion:Rudolfkoenig|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Das Modul [[HttpUtils]](.pm) ist sowohl für Modulentwickler als auch für Endanwender gedacht, um Daten via HTTP auszutauschen. Es stellt dabei eine Reihe von Funktionen zur Verfügung und wird beispielsweise vom Modul [[HTTPMOD]] intensiv genutzt.&lt;br /&gt;
&lt;br /&gt;
== Primäre Funktionen (HTTP) ==&lt;br /&gt;
Es ist zu beachten, dass bei den Funktionen&lt;br /&gt;
* &amp;lt;code&amp;gt;GetHttpFile()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;GetFileFromURL&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;GetFileFromURLQuiet&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;HttpUtils_BlockingGet&amp;lt;/code&amp;gt;&lt;br /&gt;
ein sogenannter &amp;quot;blockierender&amp;quot; Aufruf durchgeführt wird. Das bedeutet, dass FHEM bei einem Aufruf einer dieser Funktionen solange wartet und dabei absolut nichts macht, bis die Antwort vom HTTP-Server eintrifft und die Funktion damit beendet ist. Das kann bei Verbindungsproblemen evtl. dazu führen, dass FHEM für die gesamte Wartezeit (Timeout) steht und nichts verarbeitet. Problematisch ist das gerade bei Anwendungen oder Hardware, die eine zeitnahe Reaktion von FHEM erwarten (z.B. HomeMatic-Geräte). In der Zeit, in der auf eine HTTP Antwort gewartet wird, steht FHEM dabei komplett. &lt;br /&gt;
&lt;br /&gt;
Es wird daher empfohlen, die Funktionen so sparsam wie möglich zu verwenden und die Timeouts so niedrig wie möglich zu halten, um ein längeres Einfrieren von FHEM möglichst zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
Um eine Blockierung zu vermeiden wird generell die Verwendung von&lt;br /&gt;
:&amp;lt;code&amp;gt;HttpUtils_NonblockingGet&amp;lt;/code&amp;gt;&lt;br /&gt;
empfohlen. Diese führt den HTTP-Request asynchron durch, wodurch ein Blockieren von FHEM verhindert wird. Wie das genau funktioniert, wird in dem entsprechenden Kapitel beschrieben.&lt;br /&gt;
&lt;br /&gt;
=== GetHttpFile ===&lt;br /&gt;
Die Funktion GetHttpFile ist die denkbar einfachste Variante um eine URL aufzurufen. &lt;br /&gt;
:&amp;lt;code&amp;gt;GetHttpFile($server, $file)&amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$server&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der DNS-Name oder die IP-Adresse des HTTP-Servers&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;www.myhost.com&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;192.168.0.10&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$file&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Datei, welche auf dem HTTP-Server aufgerufen werden soll.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &#039;&#039;/&#039;&#039;&lt;br /&gt;
* &#039;&#039;/index.html&#039;&#039;&lt;br /&gt;
* &#039;&#039;/directory/image.jpg&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Funktionsergebnis ist der Inhalt der aufgerufenen Seite in Form einer Zeichenkette.&lt;br /&gt;
&lt;br /&gt;
=== GetFileFromURL ===&lt;br /&gt;
Die Funktion GetFileFromURL ruft die HTTP-URL auf und gibt als Funktionsergebnis den Seiteninhalt zurück. Im Gegensatz zu GetHttpFile beinhaltet GetFileFromURL einige Zusatzoptionen in Form von Funktionsparametern.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Aufruf: &amp;lt;code&amp;gt;GetFileFromURL($url, &#039;&#039;[$timeout], [$data], [$noshutdown], [$loglevel]&#039;&#039;)&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$url&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die HTTP-URL, welche aufgerufen werden soll. Diese kann optional Usernamen, Passwort und einen Port enthalten. Sowohl HTTP als auch HTTPS wird hierbei unterstützt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;http://www.myhost.com/directory/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;https://www.myhost.com/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;http://www.myhost.com:8080/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;http://user:password@www.myhost.com/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WICHTIG:&#039;&#039;&#039; Falls ein Username sowie Passwort übergeben werden, so müssen diese vorher jeweils mittels [[#urlEncode|urlEncode()]] in URL-kompatible Form umgewandelt werden um Probleme mit evtl. enthaltenen Sonderzeichen zu vermeiden. &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timeout&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Die maximale Dauer in Sekunden für die HTTP-Anfrage&lt;br /&gt;
&lt;br /&gt;
Beispiel: 5 &#039;&#039;(Sekunden)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Standardwert: 4 Sekunden&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$data&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Wenn man Daten via HTTP-POST übertragen möchte, so kann man die Nutzdaten über $data übergeben. Die Daten werden dabei als Formulardaten übertragen. Wenn man den Content-Type beeinflussen oder mehrere Formular-Felder senden möchte, sollte man zur Funktion HttpUtils_BlockingGet oder HttpUtils_NonblockingGet greifen.&lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039;&#039;[leer]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$noshutdown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Wenn $noshutdown auf 1 gesetzt ist, wird dem HTTP-Server nicht implizit mitgeteilt, dass die Verbindung nach dem Request geschlossen werden soll. Viele Webserver schließen in solch einem Fall die Verbindung, bevor sie die Antwort senden. Bei 0 wird dem Webserver mitgeteilt, dass der Sendevorgang beendet ist und nun die Antwort abgewartet wird.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$loglevel&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Das [[verbose|Loglevel]], in dem sämtliche Logmeldungen zu dieser HTTP-Abfrage erzeugt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Funktionsergebnis ist der Inhalt der aufgerufenen Seite in Form eines Strings.&lt;br /&gt;
&lt;br /&gt;
=== GetFileFromURLQuiet ===&lt;br /&gt;
Diese Funktion funktioniert ähnlich wie GetFileFromURL. Allerdings wird die tatsächliche URL in allen erzeugten Log-Meldungen unkenntlich gemacht um z.B. Zugangsdaten nicht preiszugeben. Die aufgerufene Seite wird ebenfalls als Funktionsergebnis zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Aufruf: &amp;lt;code&amp;gt;GetFileFromURLQuiet($url, &#039;&#039;[$timeout], [$data], [$noshutdown], [$loglevel]&#039;&#039;)&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter!! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$url&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die HTTP-URL, welche aufgerufen werden soll. Diese kann optional Usernamen, Passwort und einen Port enthalten. Sowohl HTTP als auch HTTPS wird hierbei unterstützt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;http://www.myhost.com/directory/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;https://www.myhost.com/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;http://www.myhost.com:8080/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;http://user:password@www.myhost.com/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WICHTIG:&#039;&#039;&#039; Falls ein Username sowie Passwort übergeben werden, so müssen diese vorher jeweils mittels [[#urlEncode|urlEncode()]] in URL-kompatible Form umgewandelt werden um Probleme mit evtl. enthaltenen Sonderzeichen zu vermeiden. &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$timeout&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Die maximale Dauer in Sekunden für die HTTP-Anfrage&lt;br /&gt;
&lt;br /&gt;
Beispiel: 5 &#039;&#039;(Sekunden)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Standardwert: 4 Sekunden&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$data&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Wenn man Daten via HTTP-POST übertragen möchte, so kann man die Nutzdaten über &amp;lt;code&amp;gt;$data&amp;lt;/code&amp;gt; übergeben. Die Daten werden dabei als Formulardaten übertragen. Wenn man den Content-Type beeinflussen möchte, oder mehrere Formular-Felder senden möchte, sollte man zur Funktion HttpUtils_BlockingGet oder HttpUtils_NonblockingGet greifen.&lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039;&#039;[leer]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$noshutdown&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Wenn $noshutdown auf 1 gesetzt ist, wird dem HTTP-Server nicht implizit mitgeteilt, dass die Verbindung nach dem Request geschlossen werden soll. Viele Webserver schließen in solch einem Fall die Verbindung bevor, sie die Antwort senden. Bei 0 wird dem Webserver mitgeteilt, dass der Sendevorgang beendet ist und nun die Antwort abgewartet wird.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$loglevel&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Das Loglevel, in dem sämtliche Logmeldungen zu dieser HTTP-Abfrage erzeugt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Funktionsergebnis ist der Inhalt der aufgerufenen Seite in Form eines Strings.&lt;br /&gt;
&lt;br /&gt;
=== HttpUtils_BlockingGet ===&lt;br /&gt;
Wenn die bisher genannten Funktionen nicht ausreichen um die gewünschte Abfrage durchzuführen, so kann man diese Funktion verwenden. Aufgrund zahlreicher Parameter ermöglicht sie viele Anpassungsmöglichkeiten. Diese Funktion hat dabei nicht wie üblich eine Liste an Funktionsparametern, sondern lediglich einen Parameter, welcher eine Hashreferenz mit allen Funktionsparametern darstellt. Dieser Hash enthält sämtliche Parameter inkl. Werten. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Aufruf: &amp;lt;code&amp;gt;HttpUtils_BlockingGet($param)&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der Parameter $param ist eine Referenz auf eine Hash-Struktur, welche die einzelnen Parameter enthält. Der Hash $param kann folgende Optionen beinhalten:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:175px&amp;quot; | Parameter !! style=&amp;quot;width:auto&amp;quot; | Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{url}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
 || Die HTTP-URL, welche aufgerufen werden soll. Diese kann optional Usernamen, Passwort und einen Port enthalten. Sowohl HTTP als auch HTTPS wird hierbei unterstützt.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;http://www.myhost.com/directory/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;https://www.myhost.com/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;http://www.myhost.com:8080/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&amp;lt;nowiki&amp;gt;http://user:password@www.myhost.com/&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WICHTIG:&#039;&#039;&#039; Alternativ können die Zugangsdaten auch in &amp;lt;code&amp;gt;$param-&amp;gt;{user}&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;$param-&amp;gt;{pwd}&amp;lt;/code&amp;gt; übergeben werden. Falls  Username und Passwort in der URL übergeben werden, so müssen diese vorher jeweils mittels [[#urlEncode|urlEncode()]] in URL-kompatible Form umgewandelt werden um Probleme mit evtl. enthaltenen Sonderzeichen (z.B. &amp;quot;:&amp;quot; und &amp;quot;@&amp;quot;) zu vermeiden, da sonst die URL nicht mehr einer validen Syntax entspricht. &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; |&#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{timeout}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Die maximale Dauer in Sekunden bis der Server eine Antwort liefern muss. Andernfalls wird der Request mit einer Fehlermeldung abgebrochen.&lt;br /&gt;
&lt;br /&gt;
Beispiel: 5 &#039;&#039;(Sekunden)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Standardwert: 4 Sekunden&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; |&#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{data}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Wenn man Daten via HTTP-POST übertragen möchte, so kann man die Nutzdaten über &amp;lt;code&amp;gt;$param-&amp;gt;{data}&amp;lt;/code&amp;gt; übergeben. Die Daten werden dabei als Formulardaten übertragen. Die Daten können dabei auf zwei Arten übergeben werden:&lt;br /&gt;
&lt;br /&gt;
1. Daten als Zeichenkette:&lt;br /&gt;
:* Die Daten werden komplett als gesamte Zeichenkette in &amp;lt;code&amp;gt;$param-&amp;gt;{data}&amp;lt;/code&amp;gt; abgelegt (z.B.: &amp;lt;code&amp;gt;$param-&amp;gt;{data} = &amp;quot;Jede Menge tolle Daten&amp;quot;&amp;lt;/code&amp;gt;).&lt;br /&gt;
2. Daten als Hash-Struktur:&lt;br /&gt;
:* Die Daten werden als Hash mit Key-Value-Pairs übergeben (z.B.: &amp;lt;code&amp;gt;$param-&amp;gt;{data}{field1} = &amp;quot;value1&amp;quot;, $param{data}{field2} = &amp;quot;value2&amp;quot;, ...&amp;lt;/code&amp;gt; ). Die Daten werden dann als Formulardaten mit mehrfachen Datenfeldern übertragen.&lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039;&#039;[leer]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{user}&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
||Im Falle einer notwendigen HTTP-Authentifizierung, der zu benutzende Username um sich gegenüber dem Server zu identifizieren. Alternativ kann der Username und das Passwort auch direkt in der URL mitgegeben werden (siehe jedoch &amp;lt;code&amp;gt;$param-&amp;gt;{hideurl}&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039;&#039;[leer]&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{pwd}&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
||Im Falle einer notwendigen HTTP-Authentifizierung, das zu benutzende Passwort um sich gegenüber dem Server zu identifizieren. Alternativ kann der Username und das Passwort auch direkt in der URL mitgegeben werden (siehe jedoch &amp;lt;code&amp;gt;$param-&amp;gt;{hideurl}&amp;lt;/code&amp;gt;).&lt;br /&gt;
Standardwert: &#039;&#039;[leer]&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{noshutdown}&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
||Wenn &amp;lt;code&amp;gt;$param-&amp;gt;{noshutdown}&amp;lt;/code&amp;gt; auf 1 gesetzt ist, wird dem HTTP-Server nicht implizit mitgeteilt, dass die Verbindung nach dem Request geschlossen werden soll. Viele Webserver schließen in solch einem Fall die Verbindung, bevor sie die Antwort senden. Bei 0 wird dem Webserver mitgeteilt, dass der Sendevorgang beendet ist und nun die Antwort abgewartet wird.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{loglevel}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Das Loglevel, in dem sämtliche Logmeldungen zu dieser HTTP-Abfrage erzeugt werden sollen.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 4&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{hideurl}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Wenn dieser Parameter den Wert 1 trägt, wird die gesamte URL in sämtlichen Log-Ausgaben unkenntlich gemacht. Dies notwendig, wenn z.B. Zugangsdaten direkt in der URL angegeben wurden, oder die URL ein geheimes Token oder andere schützenswerte Informationen enthält.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{ignoreredirects}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Wenn dieser Parameter den Wert 1 trägt, werden Umleitungen durch den Server ignoriert und der Request beendet. Dies kann erforderlich sein um evtl. Cookies aus der Antwort, welche eine Umleitung enthält aus dem HTTP Header zu extrahieren um diese im nächsten Request weiterzuverwenden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{method}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
||Die HTTP-Methode, welche zur Abfrage verwendet werden soll. Sofern keine Daten übertragen werden ist dies standardmäßig &amp;quot;GET&amp;quot;, ansonsten &amp;quot;POST&amp;quot;. Es können aber auch andere Methoden verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: &amp;quot;GET&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{keepalive}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
||Wenn dieser Parameter auf 1 gesetzt ist, wird dem Server der Wunsch mitgeteilt, die Verbindung offen zu lassen für weitere Anfragen. Sobald die Antwort auf den jeweiligen Request eintrifft, bleibt die TCP-Verbindung bestehen (sofern der Server dies unterstützt). Anschließend kann man den Parameter-Hash mit einer neuen URL und Optionen füllen. Der Parameter &amp;quot;keepalive&amp;quot; sollte dabei weiterhin gesetzt bleiben, sofern die Verbindung auch weiterhin möglichst erhalten bleiben soll. &lt;br /&gt;
&lt;br /&gt;
Um eine offene Verbindung endgültig zu schließen, muss die Funktion [[HttpUtils#HttpUtils_Close|HttpUtils_Close]] aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{header}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Eigene HTTP-Header-Zeilen können über diesen Parameter eingebracht werden. Er kann dazu genutzt werden um z.B. den Content-Type festzulegen, oder einfach nur zusätzliche Header-Felder zu setzen. Es gibt zwei Möglichkeiten, diesen Parameter zu befüllen.&lt;br /&gt;
&lt;br /&gt;
# Als &#039;&#039;&#039;Zeichenkette&#039;&#039;&#039;. Mehrere Header-Zeilen müssen dabei mit &amp;quot;\r\n&amp;quot; getrennt werden.&lt;br /&gt;
# Als &#039;&#039;&#039;Hash-Struktur&#039;&#039;&#039;. Hierbei findet eine Zuordnung von Header-Bezeichnung zum Wert als Key-Value-Pair statt.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;User-Agent: Mozilla/1.22&#039;&#039;&#039;&amp;lt;u&amp;gt;\r\n&amp;lt;/u&amp;gt;&#039;&#039;&#039;Content-Type: application/xml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;Content-Type: application/xml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{ &amp;quot;User-Agent&amp;quot; =&amp;gt;  &amp;quot;Mozilla/1.22&amp;quot;, &amp;quot;Content-Type&amp;quot; =&amp;gt; &amp;quot;application/xml&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;{ &amp;quot;Content-Type&amp;quot; =&amp;gt; &amp;quot;application/xml&amp;quot; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039;&#039;[leer]&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{sslargs}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Eigene SSL-Optionen können über diesen Parameter eingebracht werden. Er kann dazu genutzt werden um z.B. die SSL-Zertifikats Verifikation abzuschalten. Die SSL-Optionen müssen als eigene Hash-Referenz übergeben werden. Eine Liste aller möglichen Optionen findet man in der Perl-Dokumentation zu [http://search.cpan.org/~sullr/IO-Socket-SSL-2.016/lib/IO/Socket/SSL.pod#Description_Of_Methods IO::Socket::SSL].&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
* &amp;lt;code&amp;gt;$param-&amp;gt;{sslargs} = { SSL_verify_mode =&amp;gt; 0, sslOpt2 =&amp;gt; &#039;sslVal2&#039; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Standardwert: &#039;&#039;{ }&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{httpversion}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Die HTTP-Version, welche zur Abfrage verwendet werden soll. Standardmäßig werden alle Abfragen mit HTTP/1.0 durchgeführt. Falls es jedoch notwendig ist HTTP/1.1 zu verwenden, so sollte &amp;lt;code&amp;gt;$param-&amp;gt;{httpversion}&amp;lt;/code&amp;gt; auf &amp;quot;1.1&amp;quot; gesetzt werden. Bei Version 1.1 wird automatisch der Header &amp;quot;&amp;lt;code&amp;gt;Connection: close&amp;lt;/code&amp;gt;&amp;quot; implizit mitgesendet.&lt;br /&gt;
&lt;br /&gt;
Standardwert: &amp;quot;1.0&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{digest}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Wenn dieser Parameter den Wert 1 trägt, wird bei vorhandenen Authentifizierungsdaten (Username+Passwort) eine Authentifizierung via Digest-Verfahren nach RFC 2617&amp;lt;ref name=&amp;quot;rfc2617&amp;quot;&amp;gt;RFC 2617 - HTTP Authentication: Basic and Digest Access Authentication&amp;lt;/ref&amp;gt; erwartet. Die Anmeldedaten werden dann nur verwendet, wenn dieser explizit eine HTTP Digest Authentifizierung einleitet. Ist dieser Parameter nicht gesetzt (Wert: 0), wird bei vorhandenen Authentifizierungsdaten immer eine HTTP Basic&amp;lt;ref name=&amp;quot;rfc2617&amp;quot; /&amp;gt; Authentifizierung im Request mitgeschickt.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{compress}&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Wenn dieser Parameter den Wert 1 trägt, wird dem Server die Verwendung von Komprimierung in Form GZIP oder alternativ Deflate&amp;lt;ref&amp;gt;RFC 1951 - DEFLATE Compressed Data Format Specification version 1.3&amp;lt;/ref&amp;gt; zur Übertragung der Antwort ermöglicht. Die komprimierte Antwort wird dabei direkt durch HttpUtils.pm wieder dekomprimiert. Wird dieser Parameter auf den Wert 0 gesetzt, so wird keine Komrpimierung ermöglicht.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WICHTIG&#039;&#039;&#039;: Die Verwendung von Komprimierung in HttpUtils.pm kann mit dem globalen Attribut &amp;quot;httpcompress&amp;quot; (Standardwert: 1) durch setzen auf 0 für die gesamte FHEM Installation durch den Nutzer deaktiviert werden. In diesem Fall ist der Parameter &amp;lt;code&amp;gt;$param-&amp;gt;{compress} = 1&amp;lt;/code&amp;gt; wirkungslos.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Als Rückgabewert von HttpUtils_BlockingGet wird ein Array mit zwei Rückgabewerten zurückgegeben:&lt;br /&gt;
:&amp;lt;code&amp;gt;($err, $data) = HttpUtils_BlockingGet( … )&amp;lt;/code&amp;gt;&lt;br /&gt;
Diese zwei Rückgabewerte haben folgende Bedeutung:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$err&amp;lt;/code&amp;gt;&#039;&#039;&#039;|| Falls beim Aufruf der URL ein Fehler aufgetreten ist (z.B. Server nicht erreichbar oder Verbindungstimeout), dann ist dieser Wert mit einer Fehlermeldung gefüllt. &lt;br /&gt;
&lt;br /&gt;
Wenn kein Fehler aufgetreten ist, ist dieser Wert mit einem Leerstring gefüllt (&amp;lt;code&amp;gt;$err = &amp;quot;&amp;quot;&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$data&amp;lt;/code&amp;gt;&#039;&#039;&#039;|| Die Ergebnisdaten, welche der HTTP-Server zurückgeliefert hat. Die Daten werden als Klartext in Form eines gesamten Strings zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Falls ein Fehler aufgetreten ist, ist dieser Wert mit einem Leersting gefüllt (&amp;lt;code&amp;gt;$data = &amp;quot;&amp;quot;&amp;lt;/code&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== HttpUtils_NonblockingGet ===&lt;br /&gt;
{{Randnotiz|RNText=Die Funktion HttpUtils_NonblockingGet ist nicht komplett durchgehend &amp;quot;non-blocking&amp;quot;. DNS-Abfragen sind weiterhin blockierend. Insbesondere wenn der DNS-Name nicht aufgelöst werden kann.}}&lt;br /&gt;
Diese Funktion arbeitet ähnlich wie HttpUtils_BlockingGet. Allerdings wird das Ergebnis nicht als Funktionsergebnis zurückgegeben. Die Funktion HttpUtils_NonblockingGet initiiert den Verbindungsaufbau und übergibt alles weitere an FHEM interne Routinen. Sobald eine Antwort vom HTTP-Server eintrifft, wird eine Callback-Funktion mit verschiedenen Parametern (unter anderem auch das Ergebnis) aufgerufen, um die Antwort entgegenzunehmen und weiter zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf ist daher ähnlich zu HttpUtils_BlockingGet mit nur einem Parameter-Hash:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Aufruf: &amp;lt;code&amp;gt;HttpUtils_NonblockingGet($param)&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:175px&amp;quot; | Parameter !! style=&amp;quot;width:auto&amp;quot; | Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center&amp;quot; | &#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;Alle Hash-Parameter, welche für HttpUtils_BlockingGet gelten, sind auch für HttpUtils_NonblockingGet gültig&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{callback}&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine Funktion (oder eine Referenz auf eine Funktion), welche die Ergebnisdaten entgegennimmt und die Antwort entsprechend weiterverarbeitet. Die Callback-Funktion muss dabei 3 Parameter erwarten. Die Funktionsparameter der Callback-Funktion werden im nachfolgenden Abschnitt näher erläutert.&lt;br /&gt;
&lt;br /&gt;
Beispiel: &lt;br /&gt;
* &amp;lt;code&amp;gt;$param-&amp;gt;{callback} = \&amp;amp;MyCallbackFn&amp;lt;/code&amp;gt; — &#039;&#039;(Referenzzeiger auf Funktionsname)&#039;&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;$param-&amp;gt;{callback} = sub(){ … }&amp;lt;/code&amp;gt; —  &#039;&#039;(direkte Funktionsdefinition)&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;white-space:nowrap;&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{incrementalTimout}&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;optional&#039;&#039;&lt;br /&gt;
|| Sofern gesetzt (Wert: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;), wird der Timeout nach jedem Empfang von Teil-Daten wieder zurückgesetzt. So können größere Datenmengen von langsamen Sendern empfangen werden, ohne den Parameter &amp;lt;code&amp;gt;timeout&amp;lt;/code&amp;gt; zu erhöhen und dadurch tatsächliche Verbindungsprobleme erst spät zu erkennen.&lt;br /&gt;
&lt;br /&gt;
Standardwert: 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;Benutzerdefinierte Parameter&#039;&#039; &lt;br /&gt;
|| Es können im Hash weitere benutzerdefinierte Parameter gesetzt werden, welche evtl. in der Callback-Funktion benötigt werden, um die Antwort korrekt zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel im Rahmen der Modul-Programmierung wäre das &amp;lt;code&amp;gt;$hash&amp;lt;/code&amp;gt; der aktuellen Definition. Alle gesetzten Parameter sind in der Callback-Funktion wieder über &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt; direkt abrufbar und können ausgewertet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel: &lt;br /&gt;
* &amp;lt;code&amp;gt;$param-&amp;gt;{hash} = $hash&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;$param-&amp;gt;{command} = &amp;quot;on&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|} &lt;br /&gt;
&lt;br /&gt;
Ein Funktionsrückgabewert von HttpUtils_NonblockingGet existiert nicht, da die eigentliche Rückgabe der Daten über die Callback-Funktion erfolgt. Die Callback-Funktion wird aufgerufen, sobdald der HTTP-Request abgeschlossen ist, oder ein Fehler aufgetreten ist. Der Funktionsaufruf erfolgt mit den folgenden Parametern:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; &#039;&#039;MyCallbackFn&#039;&#039; ( $param, $err, $data )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese 3 Parameter haben dabei folgende Bedeutung:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Der Parameter-Hash, mit allen Argumenten die beim Aufruf der Funktion übergeben worden sind.&lt;br /&gt;
&lt;br /&gt;
Es ist möglich, dass der Parameter-Hash nach erfolgter Abfrage zusätzliche oder veränderte Elemente enthält:&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{redirects}&amp;lt;/code&amp;gt;&#039;&#039;&#039; - Die Anzahl an Umleitungen die erfolgte, bis die Anfrage beantwortet wurde.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{url}&amp;lt;/code&amp;gt;&#039;&#039;&#039; - Die URL, die nach erfolgter Umleitung die Anfrage beantwortet hat.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{protocol}&amp;lt;/code&amp;gt;&#039;&#039;&#039; - Das verwendete Protokoll, welches zur Abfrage verwendet wurde (&amp;quot;http&amp;quot; oder &amp;quot;https&amp;quot;).&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{path}&amp;lt;/code&amp;gt;&#039;&#039;&#039; - Der Pfad, welcher auf dem HTTP-Server angefragt wurde.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{host}&amp;lt;/code&amp;gt;&#039;&#039;&#039; - Der Name oder die IP-Adresse des HTTP-Servers.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{httpheader}&amp;lt;/code&amp;gt;&#039;&#039;&#039; - Der gesamte HTTP Header, welcher der Server bei der letzten Antwort zurücklieferte.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{code}&amp;lt;/code&amp;gt;&#039;&#039;&#039; - Der HTTP-Statuscode, mit dem die Anfrage vom Server beantwortet wurde.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{addr}&amp;lt;/code&amp;gt;&#039;&#039;&#039; - Die HTTP-URL ohne Pfad und evtl. Authentifizerungsinformationen des HTTP-Servers (z.B. &amp;quot;&amp;lt;nowiki&amp;gt;http://myserver.com:8080&amp;lt;/nowiki&amp;gt;&amp;quot;).&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;$param-&amp;gt;{auth}&amp;lt;/code&amp;gt;&#039;&#039;&#039; - Ein Flag (0/1) ob Zugangsdaten für den Request zur Verfügung standen (durch Angabe in der URL oder direkt in &amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$err&amp;lt;/code&amp;gt;&#039;&#039;&#039;|| Falls beim Aufruf der URL ein Fehler aufgetreten ist (z.B. Server nicht erreichbar oder Verbindungstimeout), dann ist dieser Wert mit einer Fehlermeldung gefüllt. &lt;br /&gt;
&lt;br /&gt;
Wenn kein Fehler aufgetreten ist, ist dieser Wert mit einem Leerstring gefüllt (&amp;lt;code&amp;gt;$err = &amp;quot;&amp;quot;&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$data&amp;lt;/code&amp;gt;&#039;&#039;&#039;|| Die Ergebnisdaten, welche der HTTP-Server zurückgeliefert hat. Die Daten werden als Klartext in Form eines gesamten Strings zurückgegeben. Es handelt sich hierbei ausschließlich um den HTTP-Body. &lt;br /&gt;
&lt;br /&gt;
Falls ein Fehler aufgetreten ist, ist dieser Wert mit einem Leersting gefüllt (&amp;lt;code&amp;gt;$data = &amp;quot;&amp;quot;&amp;lt;/code&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die Callback-Funktion kann nun die Daten aus der HTTP-Antwort verarbeiten oder bei Fehlern entsprechende Log-Meldungen ausgeben.&lt;br /&gt;
&lt;br /&gt;
==== Beispiel für HttpUtils_NonblockingGet() für Modulprogrammierer ====&lt;br /&gt;
Das folgende Beispiel soll eine Hilfestellung für eigene Anwendungen geben&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;use HttpUtils;&lt;br /&gt;
sub X_PerformHttpRequest($)&lt;br /&gt;
{&lt;br /&gt;
    my ($hash, $def) = @_;&lt;br /&gt;
    my $name = $hash-&amp;gt;{NAME};&lt;br /&gt;
    my $param = {&lt;br /&gt;
                    url        =&amp;gt; &amp;quot;http://www.foo.de/&amp;quot;,&lt;br /&gt;
                    timeout    =&amp;gt; 5,&lt;br /&gt;
                    hash       =&amp;gt; $hash,                                                                                 # Muss gesetzt werden, damit die Callback funktion wieder $hash hat&lt;br /&gt;
                    method     =&amp;gt; &amp;quot;GET&amp;quot;,                                                                                 # Lesen von Inhalten&lt;br /&gt;
                    header     =&amp;gt; &amp;quot;User-Agent: TeleHeater/2.2.3\r\nAccept: application/json&amp;quot;,                            # Den Header gemäß abzufragender Daten ändern&lt;br /&gt;
                    callback   =&amp;gt; \&amp;amp;X_ParseHttpResponse                                                                  # Diese Funktion soll das Ergebnis dieser HTTP Anfrage bearbeiten&lt;br /&gt;
                };&lt;br /&gt;
&lt;br /&gt;
    HttpUtils_NonblockingGet($param);                                                                                    # Starten der HTTP Abfrage. Es gibt keinen Return-Code. &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub X_ParseHttpResponse($)&lt;br /&gt;
{&lt;br /&gt;
    my ($param, $err, $data) = @_;&lt;br /&gt;
    my $hash = $param-&amp;gt;{hash};&lt;br /&gt;
    my $name = $hash-&amp;gt;{NAME};&lt;br /&gt;
&lt;br /&gt;
    if($err ne &amp;quot;&amp;quot;)                                                                                                      # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist&lt;br /&gt;
    {&lt;br /&gt;
        Log3 $name, 3, &amp;quot;error while requesting &amp;quot;.$param-&amp;gt;{url}.&amp;quot; - $err&amp;quot;;                                               # Eintrag fürs Log&lt;br /&gt;
        readingsSingleUpdate($hash, &amp;quot;fullResponse&amp;quot;, &amp;quot;ERROR&amp;quot;, 0);                                                        # Readings erzeugen&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    elsif($data ne &amp;quot;&amp;quot;)                                                                                                  # wenn die Abfrage erfolgreich war ($data enthält die Ergebnisdaten des HTTP Aufrufes)&lt;br /&gt;
    {&lt;br /&gt;
        Log3 $name, 3, &amp;quot;url &amp;quot;.$param-&amp;gt;{url}.&amp;quot; returned: $data&amp;quot;;                                                         # Eintrag fürs Log&lt;br /&gt;
&lt;br /&gt;
        # An dieser Stelle die Antwort parsen / verarbeiten mit $data&lt;br /&gt;
&lt;br /&gt;
        readingsSingleUpdate($hash, &amp;quot;fullResponse&amp;quot;, $data, 0);                                                          # Readings erzeugen&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Damit ist die Abfrage zuende.&lt;br /&gt;
    # Evtl. einen InternalTimer neu schedulen&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HttpUtils_Close ===&lt;br /&gt;
&lt;br /&gt;
Für den Abbruch von offenen Verbindungen und noch laufenden NonBockingGet-Aufrufen gibt es die Funktion HttpUtils_Close. Diese kann z.B. beim Löschen eines Devices oder Herunterfahren des Servers aufgerufen werden, um bestehende Verbindungen zu schliessen.&lt;br /&gt;
&lt;br /&gt;
Wenn man den Parameter &amp;quot;keepalive&amp;quot; beim Aufruf von HttpUtils_NonBlockingGet/HttpUtils_BlockingGet gesetzt hat, muss man HttpUtils_Close aufrufen um die Verbindung tatsächlich zu schließen, da diese noch durch den Server offen gehalten werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Aufruf: &amp;lt;code&amp;gt;HttpUtils_Close($param)&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:175px&amp;quot; | Parameter !! style=&amp;quot;width:auto&amp;quot; | Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$param&amp;lt;/code&amp;gt;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Der Hash, der beim vorherigen Aufruf an HTTPUtils Funktionen (HttpUtils_NonblockingGet oder HttpUtils_BlockingGet) übergeben wurde&lt;br /&gt;
&lt;br /&gt;
|} &lt;br /&gt;
&lt;br /&gt;
== Hilfsfunktionen ==&lt;br /&gt;
&lt;br /&gt;
=== urlEncode ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$encoded = urlEncode($string);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion urlEncode() wandelt die übergebene Zeichenkette &amp;lt;code&amp;gt;$string&amp;lt;/code&amp;gt; in eine URL-kompatible&amp;lt;ref name=&amp;quot;rfc3986-2.1&amp;quot;&amp;gt;[https://tools.ietf.org/html/rfc3986#section-2.1 RFC 3989] - Abschnitt 2.1 &amp;quot;Percent-Encoding&amp;quot;&amp;lt;/ref&amp;gt; Zeichenkette um. Der Rückgabewert &amp;lt;code&amp;gt;$encoded&amp;lt;/code&amp;gt; ist eine Zeichenkette welche innerhalb einer URL verwendet werden kann, bspw. als Wert eines GET-Parameters.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$string&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Die Zeichenkette, welche in eine URL-kompatible Form umgewandelt werden soll.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$encoded &amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die URL-kompatible Version der übergebenen Zeichenkette. Problematische Zeichen sind in diesem Wert durch ein Prozentzeichen gefolgt von der Hexadezimaldarstellung des Zeichens dargestellt.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;quot;a: b&amp;quot; =&amp;gt; &amp;quot;a%3a%20b&amp;quot;&lt;br /&gt;
* &amp;quot;a/b&amp;quot; =&amp;gt; &amp;quot;a%2fb&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== urlDecode ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
$string = urlDecode($encoded);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion urlDecode () normalisiert die übergebene Zeichenkette &amp;lt;code&amp;gt;$encoded&amp;lt;/code&amp;gt; und ersetzt dabei sämtliche Hexadezimaldarstellungen&amp;lt;ref name=&amp;quot;rfc3986-2.1&amp;quot; /&amp;gt; (eingeleitet mit einem Prozentzeichen) durch die entsprechenden Zeichen. Der Rückgabewert &amp;lt;code&amp;gt;$string&amp;lt;/code&amp;gt; ist eine Zeichenkette welche keinerlei Hexadezimaldarstellungen mehr aufweist.&lt;br /&gt;
&lt;br /&gt;
Parameter:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$encoded&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mandatory&#039;&#039;&lt;br /&gt;
|| Eine Zeichenkette, welche URL-kombatible Hexadezimaldarstellungen enthält.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Rückgabewerte:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Rückgabewert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; | &#039;&#039;&#039;&amp;lt;code&amp;gt;$string&amp;lt;/code&amp;gt;&#039;&#039;&#039; || Die normale Version der übergebenen Zeichenkette. Sämtliche Hexadezimalddarstellungen sind in ihre entsprechenden Zeichen umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
* &amp;quot;a%3a%20b&amp;quot; =&amp;gt; &amp;quot;a: b&amp;quot;&lt;br /&gt;
* &amp;quot;a%2fb&amp;quot; =&amp;gt; &amp;quot;a/b&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Referenzen ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Development]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Buienradar&amp;diff=33252</id>
		<title>Buienradar</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Buienradar&amp;diff=33252"/>
		<updated>2020-05-19T12:10:43Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Added external links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the [https://github.com/fhem/mod-Buienradar/wiki project wiki] and the documentation ([https://github.com/fhem/mod-Buienradar/blob/stable/CommandRef.en.md english], [https://github.com/fhem/mod-Buienradar/blob/stable/CommandRef.de.md german]).&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=99_myUtils_anlegen&amp;diff=32609</id>
		<title>99 myUtils anlegen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=99_myUtils_anlegen&amp;diff=32609"/>
		<updated>2020-02-04T11:42:12Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Linked 99_Utils from SVN&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Speicherung von Perl-Code unmittelbar in [[Eventhandler|Eventhandlern]], [[Timehandler|Timehandlern]] oder anderen Geräten in der [[Konfiguration]], in denen Perl-Ausdrücke angegeben werden können, wird mit wachsender Zahl von Geräten und Logiken eventuell unübersichtlich. Um z.B. Doppelungen zu vermeiden und Logikbausteine zentral vorzuhalten, kann man eine oder mehrere eigene Programmdateien erzeugen, in der diese als kleine Programme gesammelt und dann aus entsprechenden Geräten aufgerufen werden können.&lt;br /&gt;
== Eine neue Programmdatei erzeugen ==&lt;br /&gt;
FHEM enthält eine Vorlage &#039;&#039;myUtilsTemplate.pm&#039;&#039;, die zur Erzeugung von Programmdateien genutzt werden sollte; nachfolgend soll beispielhaft eine Datei namens &#039;&#039;99_myUtils.pm&#039;&#039; verwendet werden. &lt;br /&gt;
Vorgehensweise:&lt;br /&gt;
* FHEM-Menüpunkt {{Taste|Edit files}} anklicken&lt;br /&gt;
* Weblink &#039;&#039;myUtilsTemplate.pm&#039;&#039; anklicken&lt;br /&gt;
* Im Textfeld hinter &#039;&#039;Save as&#039;&#039; den Dateinamen &#039;&#039;99_myUtils.pm&#039;&#039; für die Programmdatei  eintragen&lt;br /&gt;
: Hinweis: Wenn ein anderer Dateiname angegeben wird, muss der Name Initialize-Routine entsprechend angepasst werden (siehe nachfolgende Erläuterung zur Grundstruktur unter Nr. 3)&lt;br /&gt;
* {{Taste|Save as}} anklicken&lt;br /&gt;
Nun ist die eigene Programmdatei &#039;&#039;99_myUtils.pm&#039;&#039; mit der notwendigen Grundstruktur unter dem Menüpunkt &#039;&#039;Edit files&#039;&#039; zur Bearbeitung mit dem [[codemirror|Integrierter Editor]] zu finden. Für eine einfache und fehlerminimierende Bearbeitung sollten die [[Konfiguration#Syntaxhervorhebung|Syntaxhervorhebungs-, Befehlsauswahl- und Befehlsvervollständigungsfunktionen]] im Integrierten Editor eingeschaltet sein.&lt;br /&gt;
&lt;br /&gt;
{{Randnotiz|RNTyp=g|RNText=Nutzt man {{Link2CmdRef|Lang=en|Anker=configDB|Label=configDB}}, können (bzw. sollten) die eigenen Programmdateien in die Datenbank importiert werden, statt unmittelbar im Dateisystem gespeichert zu bleiben. Sie können dann weiter über {{Taste|Edit files}} bearbeitet werden, stehen dann aber z.B. bei einem Umzug oder Neuaufsetzen des Systems direkt wieder zur Verfügung.}}&lt;br /&gt;
Die Programmdateien können zwar auch mit einem [[Konfiguration#Externer Editor|externen Editor]] bearbeitet werden, diese Vorgehensweise wird jedoch nicht empfohlen, da dies insbesondere Einsteigern das debugging erschwert.&lt;br /&gt;
&lt;br /&gt;
Eine ‚leere‘ Programmdatei muss grundsätzlich folgenden Grundstruktur besitzen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 package main;&lt;br /&gt;
 use strict;&lt;br /&gt;
 use warnings;&lt;br /&gt;
 use POSIX;&lt;br /&gt;
 sub&lt;br /&gt;
 myUtils_Initialize($$)&lt;br /&gt;
 {&lt;br /&gt;
   my ($hash) = @_;&lt;br /&gt;
 }&lt;br /&gt;
 1;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgende Dinge sind für eigene Programmdateien besonders zu beachten:&lt;br /&gt;
&lt;br /&gt;
# 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 der [[Konfiguration]] angefordert werden. So wird z.B. 10_FS20.pm erst geladen, wenn beim Einlesen der Konfiguration 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.&lt;br /&gt;
# Damit die neue Datei bei &#039;&#039;Edit files&#039;&#039; angezeigt wird, muss sie mit &#039;&#039;Utils.pm&#039;&#039; enden. Also zum Beispiel &#039;&#039;99_meineUtils.pm&#039;&#039; oder &#039;&#039;99_myUtils_Homematic.pm&#039;&#039;.&lt;br /&gt;
# 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.&lt;br /&gt;
# Die Zeile &amp;lt;code&amp;gt; 1; &amp;lt;/code&amp;gt; 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 &amp;lt;code&amp;gt; 1; &amp;lt;/code&amp;gt; ein.&lt;br /&gt;
&lt;br /&gt;
== Eigene Routinen einfügen ==&lt;br /&gt;
Als Beispiel dient das Umsetzen von FS20 toggle-Events aus dem Artikel &amp;quot;[[FS20 Toggle Events auf On/Off umsetzen]]&amp;quot;.&lt;br /&gt;
Das gesamte Programm sieht dann folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
package main;&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
use POSIX;&lt;br /&gt;
sub&lt;br /&gt;
myUtils_Initialize($$)&lt;br /&gt;
{&lt;br /&gt;
  my ($hash) = @_;&lt;br /&gt;
}&lt;br /&gt;
##########################################################&lt;br /&gt;
# Untoggle&lt;br /&gt;
# toggle-Vorgänge in den Status on/off umsetzen&lt;br /&gt;
sub Untoggle($) {&lt;br /&gt;
  my ($obj) = @_;&lt;br /&gt;
&lt;br /&gt;
  if( Value($obj) eq &amp;quot;toggle&amp;quot; ){&lt;br /&gt;
    if( OldValue($obj) eq &amp;quot;off&amp;quot; ) {&lt;br /&gt;
      fhem( &amp;quot;setstate $obj on&amp;quot; );&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      fhem( &amp;quot;setstate $obj off&amp;quot; );&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    fhem( &amp;quot;setstate $obj &amp;quot;.Value($obj) );&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
1;&amp;lt;/source&amp;gt;&lt;br /&gt;
Der Aufruf erfolgt dann z.B. so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;#fhem.cfg&lt;br /&gt;
define lampe_untoggle notify lampe {Untoggle(&amp;quot;$NAME&amp;quot;)}&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;quot;$NAME&amp;quot;).&lt;br /&gt;
Im Programm wurde die Routine Untoggle mit &#039;&#039;&#039;einem&#039;&#039;&#039; Parameter definiert ( Untoggle($) , die Anzahl der $-Zeichen bestimmt die Anzahl der zu übergebenden Parameter). Der Wert des übergebenen Parameters wird in der ersten Programmzeile in die Variable $obj übernommen (my ($obj) = @_; ). &lt;br /&gt;
Der Aufruf erfolgt mit Untoggle(„$NAME“) . Der Platzhalter $NAME in fhem steht für den Namen des Geräts. Im o.g. Beispiel erfolgt der Aufruf also eigentlich mit Untoggle(„lampe“). Natürlich können beim Aufruf auch feste Werte ( „lampe1“ ) oder Variablen ( $hour ) übergeben werden.&lt;br /&gt;
&lt;br /&gt;
=== Routinen mit mehreren Parametern ===&lt;br /&gt;
In der Definition der Routine geben Sie außerdem an, wieviele Parameter übergeben werden sollen, für 2 Parameter z.B. so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;define test at *09:00 { wakeup($we, &amp;quot;Schlafzimmerlampe&amp;quot;) }&amp;lt;/source&amp;gt;&lt;br /&gt;
Die Deklaration der Routine in Ihrer Programmdatei muss dann so beginnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;#Nur am Wochenende eingeschaltet&lt;br /&gt;
sub wakeup($$) {&lt;br /&gt;
  my ($wochenende, $device) = @_;&lt;br /&gt;
  if ($wochenende) {&lt;br /&gt;
    fhem( &amp;quot;set $device on&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    fhem( &amp;quot;set $device off&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
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&amp;lt;ref&amp;gt;Mehr zu diesen sog. prototypes ist z.B. [https://perldoc.perl.org/perlsub.html#Prototypes hier] nachzulesen; auch [[fhem.pl]] beginnt mit einer Liste der prototyes der darin enthaltenen Funktionen. Da diese Funktionen auch innerhalb der myUtils verwendet werden können, empfiehlt es sich, zunächst dort nachzusehen, ob eventuell bereits hilfreiche Funktionen für das zu lösende Problem vorhanden sind.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Routinen ohne Parameter ===&lt;br /&gt;
Auch Routinen ohne Parameter sind natürlich möglich. Definition und Aufruf sehen dann folgendermassen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;sub parameterlos() {&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
 { parameterlos() }&lt;br /&gt;
&lt;br /&gt;
== Eigene Programmdatei laden ==&lt;br /&gt;
Die Programmdatei wird beim FHEM-Start immer automatisch geladen. &lt;br /&gt;
&lt;br /&gt;
Bei Änderungen an der Programmdatei bei laufendem FHEM ist bezüglich Neuladen ohne FHEM-Neustart zwischen den verschiedenen Bearbeitungsvarianten der Progammdatei zu unterscheiden.&lt;br /&gt;
&lt;br /&gt;
Bei der Bearbeitung über den &#039;&#039;&#039;Integrierten Editor&#039;&#039;&#039; wird die Programmdatei beim Abspeichern automatisch mit den Änderungen neu geladen.&lt;br /&gt;
&lt;br /&gt;
Bei der nicht empfohlenen Bearbeitung der Programmdatei mit einem &#039;&#039;&#039;externen Editor&#039;&#039;&#039; muss FHEM manuell angewiesen werden, die Programmdatei mit den Änderungen zu laden. Also bearbeiten Sie Ihr Programm, speichern die Programmdatei, und weisen FHEM dann explizit an, die Programmdatei erneut zu laden. Der Befehl dazu, der in das Befehls-Eingabefeld eingegeben wird, lautet: &amp;lt;code&amp;gt;reload 99_myUtils.pm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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). Es empfiehlt sich daher bei der Entwicklung neuer Code-Teile v.a. für &amp;quot;Einsteiger&amp;quot;, diese zunächst in einer separaten myUtils-Datei zu entwickeln und erst dann in die für den &amp;quot;produktiven Betrieb&amp;quot; genutzten myUtils-Dateien zu übernehmen, wenn sie als funktional getestet anzusehen sind.&lt;br /&gt;
== Eigene Programmdatei dokumentieren ==&lt;br /&gt;
In der lokalen Commandref kann man die eigenen Routinen auch dokumentieren.&lt;br /&gt;
Dazu muss am Ende der 99_myUtils folgender Codeblock eingefügt werden&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
=pod&lt;br /&gt;
=begin html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;a name=&amp;quot;myUtils&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;myUtils&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
  Text&amp;lt;br&amp;gt;&lt;br /&gt;
  Examples:&lt;br /&gt;
  &amp;lt;ul&amp;gt;&lt;br /&gt;
   &amp;lt;code&amp;gt;Example Code &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=end html&lt;br /&gt;
=begin html_DE&lt;br /&gt;
&lt;br /&gt;
&amp;lt;a name=&amp;quot;myUtils&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;myUtils&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=end html_DE&lt;br /&gt;
=cut&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der a Tag stellt einen Verweis dar, der h3 Tag kennzeichnet die Überschrift. Beide Tags müssen sein, ansonsten kann FHEM die Doku nicht in die commandref einbinden. Der Abschnitt für die deutsche Doku kann komplett fehlen. Die Beschreibungen der einzelnen Routinen werden mit ul Tags geklammert und eventuell mit ul Tags weiter untergliedert. Dabei entsteht ein eingerückter Text. Beispiele können mit dem code Tag formatiert werden.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Befehl kann die Erzeugung des Commandrefeintrages initiiert und getestet werden:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;{system(&amp;quot;/usr/bin/perl ./contrib/commandref_join.pl&amp;quot;)}&amp;lt;/source&amp;gt;&lt;br /&gt;
Für eine schnelle Überprüfung des Commandrefeintrages können Sie auch &amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;help myUtils&amp;lt;/source&amp;gt; (bzw. statt myUtils den Namen Ihrer Utils-Datei) eingeben.&lt;br /&gt;
&lt;br /&gt;
== Weitere Informationen ==&lt;br /&gt;
=== Globale Ablage von Daten ===&lt;br /&gt;
Um Daten zentral zwischenzuspeichern, kann man &lt;br /&gt;
* die Funktionen &#039;&#039;[[DevelopmentModuleAPI#setKeyValue|setKeyValue()]]&#039;&#039; bzw. &#039;&#039;getKeyValue()&#039;&#039; nutzen, um die Daten im Dateisystem abzulegen;&lt;br /&gt;
* in den globalen Hash &#039;&#039;%data schreiben&#039;&#039;, wie in diesem {{Link2Forum|Topic=63737|LinkText=Forumsbeitrag}} erläutert.&lt;br /&gt;
&lt;br /&gt;
=== Vertiefende Informationen ===&lt;br /&gt;
Weiterführende Hinweise, z.B. wie aus einer Sammlung kleiner Tools ggf. ein eigenes Modul entstehen kann, sind der [[DevelopmentModuleIntro]] zu entnehmen. Dort sind v.a. auch einige häufig benötigte Funktionen aus fhem.pl dokumentiert.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* Eine Zusammenstellung wichtiger Funktionen ist in den Perl specials der {{Link2CmdRef|Anker=perl|Label=commandref}} enthalten.&lt;br /&gt;
* Eine weitere Sammlung hilfreicher &amp;quot;Helferlein&amp;quot; samt Hilfe enthält [https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/99_Utils.pm 99_Utils.pm].&lt;br /&gt;
* Hilfsfunktionen für Farboperationen: [[Color]].&lt;br /&gt;
* [[Zeitangaben, rechnen mit|Wiki-Beitrag zum Rechnen mit Zeitangaben]]&lt;br /&gt;
* [[Gleitende Mittelwerte berechnen und loggen]]&lt;br /&gt;
* Beispiele für Geräteüberwachungen: [[EBUS#Mithilfe von FHEM|EBUS]], [[Netzwerkgeräte:_Verfügbarkeit_prüfen#Erweiterung 99 myUtils|Netzwerkgeräte]], {{Link2Forum|Topic=51267|Message=935071|LinkText=Nextion-Display bei Inaktivität zurücksetzen}}, {{Link2Forum|Topic=97173|Message=917347|LinkText=devStateIcon für das Modul &#039;&#039;monitoring&#039;&#039;}}&lt;br /&gt;
* [[Batterieüberwachung#Alternativ per Skript|Batterieüberwachung]]&lt;br /&gt;
* Routine zum [[E-Mail_senden#Raspberry Pi|E-Mail senden]] aus FHEM heraus&lt;br /&gt;
* [[E-Mail per notify nach Zeitablauf erneut senden|Beispiel]], wie ggf. an mehreren Stellen relevante Variablen zentral zur Verfügung gestellt werden können.&lt;br /&gt;
* [[Plot-Abriss_vermeiden#Implementierung|Plot-Abrisse vermeiden]]&lt;br /&gt;
* Formatierungsanweisungen auslagern: [[ReadingsGroup#Enigma_Receiver|ReadingsGroup]], [[Spritpreismonitor#Farbliche_Hervorhebung|Spritpreismonitor]], [[EBUS-MQTT2#myUtils-Code|Balkenanzeige]] (hier: für EBUS)&lt;br /&gt;
* Befehle an ein Netzwerkgerät senden: [[Listenlive#Der Code|Listenlive]]&lt;br /&gt;
* [[HM-Dis-WM55_Funk_Statusanzeige#99_myUtils|Homematic-Display]] mit Informationen versorgen&lt;br /&gt;
* {{Link2Forum|Topic=34363|Message=266811|LinkText=Zeit- und Datumsvariablen $hour, $wday, $month, ... in 99_myUtils.pm verfügbar machen}}&lt;br /&gt;
* {{Link2Forum|Topic=36504|Message=287778|LinkText=Globale und flexible Fenster- und Türüberwachung}}&lt;br /&gt;
* {{Link2Forum|Topic=87895|Message=803439|LinkText=57_CALENDAR.pm - events mit deviceNames nutzen}}&lt;br /&gt;
* {{Link2Forum|Topic=96959|Message=901268|LinkText=Konstanten für das Rechnen mit Zeiten}}&lt;br /&gt;
* {{Link2Forum|Topic=97430|Message=906576|LinkText=devStateIcon-Code für Homematic-Thermostate}}&lt;br /&gt;
* {{Link2Forum|Topic=86073|Message=836537|LinkText=php-Script aufrufen und Rückgabewert in einen dummy schreiben}} (hier: Viessmann Heizung))&lt;br /&gt;
* {{Link2Forum|Topic=84831|Message=771485|LinkText=Windchill und Hitzeindex berechnen}}&lt;br /&gt;
* {{Link2Forum|Topic=84016|Message=762888|LinkText=Countdown Timer}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;br /&gt;
[[Kategorie:HOWTOS]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Buienradar&amp;diff=31023</id>
		<title>Buienradar</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Buienradar&amp;diff=31023"/>
		<updated>2019-07-22T19:01:54Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Die Seite wurde neu angelegt: „tbd“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;tbd&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=AutoShuttersControl&amp;diff=30957</id>
		<title>AutoShuttersControl</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=AutoShuttersControl&amp;diff=30957"/>
		<updated>2019-07-11T13:50:24Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Baustelle}}&lt;br /&gt;
{{Infobox Modul&lt;br /&gt;
|ModPurpose=Steuerung von Rollläden&lt;br /&gt;
|ModCategory=Automatisierung&lt;br /&gt;
|ModType=d&lt;br /&gt;
|ModForumArea=Automatisierung&lt;br /&gt;
|ModTechName=73_AutoShuttersControl.pm&lt;br /&gt;
|ModOwner=CoolTux ({{Link2FU|13684|Forum}}/[[Benutzer Diskussion:CoolTux|Wiki]])}}&lt;br /&gt;
&lt;br /&gt;
Mit [[AutoShuttersControl]] oder kurz ASC können typische Aufgabenstellungen im Zusammenhang mit Rollläden u.ä. automatisiert werden, wie zum Beispiel das Öffnen bei Sonnenaufgang, Schließen bei Sonnenuntergang oder das Anfahren von Lüftungspositionen beim Öffnen des zugehörigen Fensters. &lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
{{Hinweis|Das Modul befindet sich derzeit noch in der Entwicklung; der jeweils aktuelle Stand ist  diesem {{Link2Forum|Topic=90751|LinkText=&amp;quot;Thread im Forum&amp;quot;}} zu entnehmen.}}&lt;br /&gt;
Zur Nutzung des Moduls sollten folgende andere FHEM-Devices vorhanden sein:&lt;br /&gt;
* Rollläden&lt;br /&gt;
* Fensterkontakte und &lt;br /&gt;
* Bewohnerstatus auf Basis von Residents/Roomates in englisch. Ersatzweise andere Devices, z.B. Dummys, welche als &#039;&#039;state&#039;&#039; &#039;&#039;home&#039;&#039;, &#039;&#039;asleep&#039;&#039;, &#039;&#039;gotosleep&#039;&#039; und &#039;&#039;awoken&#039;&#039; setzen sowie ein Reading &#039;&#039;lastState&#039;&#039;.&lt;br /&gt;
* Optional:&lt;br /&gt;
** Ein Helligkeitssensor (Steuerung nach Helligkeit und Beschattung)&lt;br /&gt;
** Ein Device zur Bestimmung des Sonnenstands (nur für Beschattung). Unterstützt werden derzeit [[Modul Astro|Astro]] und [[Twilight]]&amp;lt;ref&amp;gt;Dabei müssen ggf. in [[Global|global]] auch Angaben zu &#039;&#039;longitude&#039;&#039; und &#039;&#039;latitude&#039;&#039; vorhanden sein&amp;lt;/ref&amp;gt;. &lt;br /&gt;
** Wenn Feiertage berücksichtigt werden sollen: Ein oder mehrere {{Link2CmdRef|Anker=holiday2we|Lang=en|Label=holiday2we}}-Angaben in [[Global|global]] samt entsprechender [[Wochenende, Feiertage und Schulferien#Feiertage mittels holiday-Datei|holiday]]-Dateien&amp;lt;ref&amp;gt;Es kann auch z.B. ein Dummy-Device verwendet werden, dieses sollte dann aber neben dem eigentlichen Feiertags-&#039;&#039;state&#039;&#039; auch in einem Reading &#039;&#039;tomorrow&#039;&#039; Angaben zu anstehenden Feiertagen enthalten.&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;Bitte verfahren Sie entsprechend, wenn Urlaubs- oder Ferientage wie Feiertage behandelt werden sollen.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Die Einrichtung des Moduls bzw. dessen Funktionalität erfolgt in mehreren Schritten:&lt;br /&gt;
* Definition des ASC-Devices&lt;br /&gt;
* Einstellung zentraler Vorgaben am ASC-Device&lt;br /&gt;
* Markieren der zukünftig zu steuernden Rollladen-Devices&lt;br /&gt;
* Einbinden der Rollladen-Devices in das ASC-Device&lt;br /&gt;
* Einstellen der individuellen Vorgaben je Rollladen (am Rollladen-Device)&lt;br /&gt;
Dabei geht man am einfachsten schrittweise vor und erweitert die Funktionalität nach und nach um die gewünschten Funktionen. Dann benötigt man jeweils nur einen kleinen Teil der vielen per Attribut einstellbaren Optionen, und kann die Auswirkungen der jeweiligen Änderung besser nachvollziehen. &lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
{{Hinweis|ASC kann auch verwendet werden, um lediglich Teilaufgaben der Rollladensteuerung zu erfüllen, also z.B. nur das morgendliche Öffnen der Rollläden. Allerdings geht dabei ein erheblicher Teil des Komforts verloren, der dadurch entsteht, dass die Steuerung innerhalb der vollintegrierten Lösung jeweils nachvollzieht, aus welchem Grund eine Fahrt erfolgt war und dies ggf. bei der nächsten Aktion berücksichtigt.}}&lt;br /&gt;
&lt;br /&gt;
=== Vorbereitung ===&lt;br /&gt;
Zunächst sollten die in den [[#Basics|Basics]] beschriebenen Geräte vorhanden und funktionsfähig sein. &lt;br /&gt;
&lt;br /&gt;
=== Define des ASC-Devices ===&lt;br /&gt;
Es genügt ein einfaches define ohne weitere Parameter.&lt;br /&gt;
&amp;lt;code&amp;gt;define &amp;lt;name&amp;gt; AutoShuttersControl&amp;lt;/code&amp;gt;&lt;br /&gt;
Dies bewirkt neben der Anlage des Devices selbst auch, dass als weiteres globales Attribut &#039;&#039;ASC&#039;&#039; verfügbar wird.&lt;br /&gt;
&lt;br /&gt;
=== Einstellung zentraler Vorgaben ===&lt;br /&gt;
Es stehen am ASC-Device einige Attribute zur Verfügung, über die sich das Verhalten des ASC-Devices insgesamt steuern lässt, z.B. zur Vermeidung von morgendlichen oder abendlichen Fahrten sowie bei Gefahr von Schäden an den Rollläden durch Frost oder zur Reaktion auf Fensterkontakte. Details sind der Commandref zu entnehmen.&lt;br /&gt;
Diese Attribute können auch nachträglich noch geändert werden.&lt;br /&gt;
&lt;br /&gt;
=== Markieren zu steuernder Rollladen-Devices ===&lt;br /&gt;
Um einen oder mehrere Rollläden durch das ASC-Device zu steuern, wird für jeden Rollladen jeweils das neue globale Attribut &#039;&#039;ASC&#039;&#039; gesetzt. Der Wert ist mit 1 oder 2 festzulegen, wobei &#039;&#039;&#039;1&#039;&#039;&#039; bedeutet, dass &lt;br /&gt;
* die Offen-Position kleiner ist als die Geschlossen-Position, also typischerweise 0 &#039;&#039;offen&#039;&#039; bedeutet und 100 für &#039;&#039;geschlossen&#039;&#039; steht&lt;br /&gt;
* eine bestimmte Position mit &#039;&#039;&#039;position&#039;&#039;&#039; angefahren wird, also z.B. &amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; position 70&amp;lt;/code&amp;gt;.&lt;br /&gt;
Dies ist z.B. die  passende Wahl für ROLLO-Devices&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;2&#039;&#039;&#039; steht für ein umgekehrtes Verhalten und den Befehlsteil &#039;&#039;pct&#039;&#039;, also &#039;&#039;offen&#039;&#039; für &amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; pct 100&amp;lt;/code&amp;gt;. Typischer Vertreter dieses Typs sind HomeMatic (CUL_HM-) Geräte oder die Shelly2-Aktoren.&lt;br /&gt;
&lt;br /&gt;
=== Einbinden in das ASC-Device ===&lt;br /&gt;
Nachdem man das obige Attribut bei einem oder mehreren Rollladen-Devices gesetzt hat, kann mit &lt;br /&gt;
&amp;lt;code&amp;gt;set &amp;lt;name&amp;gt; scanForShutters&amp;lt;/code&amp;gt; ein Suchlauf gestartet werden, mit dem dann diese Rollläden durch das Modul gefunden und in die Steuerungslogik eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
=== Einstellen der individuellen Vorgaben ===&lt;br /&gt;
Nach der Einbindung sind an den Rollladen-Devices weitere Attribute verfügbar, mit denen die für den jeweiligen Rollladen geltenden Einstellungen vorgenommen werden können. &lt;br /&gt;
Die Beschreibung der Attribute ist in der commandref enthalten.&lt;br /&gt;
&lt;br /&gt;
== Readings ==&lt;br /&gt;
&lt;br /&gt;
===Readings im ASC-Device selbst ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Datentyp/&amp;lt;BR/&amp;gt;Wertebereich !! Bedeutung  &lt;br /&gt;
|-&lt;br /&gt;
|..._nextAstroTimeEvent || ||Uhrzeit des nächsten Astro-Events, Sonnenauf- oder Sonnenuntergang oder feste Zeit pro Rollonamen &lt;br /&gt;
|-&lt;br /&gt;
|..._lastPosValue || ||zuletzt abgesetzter Fahrbefehl pro Rollonamen&lt;br /&gt;
|-&lt;br /&gt;
|..._lastDelayPosValue || ||zuletzt abgesetzter Fahrbefehl, welcher beim nächsten zulässigen Event ausgeführt wird&lt;br /&gt;
|-&lt;br /&gt;
|partyMode ||on, off || aktiviert den globalen Partymodus. Alle Rollläden, welche das Attribut &#039;&#039;AutoShuttersControl_Partymode&#039;&#039; bei sich auf &#039;&#039;on&#039;&#039; gestellt haben, werden nicht mehr gesteuert. Der letzte Schaltbefehl, welcher durch ein Fensterevent oder Bewohnerstatus an die Rollläden gesendet wurde, wird erst beim off-setzen (set &amp;lt;ASC-Device&amp;gt; partyMode off) ausgeführt&lt;br /&gt;
|-&lt;br /&gt;
|lockOut || on, off ||für das Aktivieren des Aussperrschutzes gemäß des entsprechenden Attributs &#039;&#039;AutoShuttersControl_lock-out&#039;&#039; im jeweiligen Rolladen (siehe Beschreibung bei den Attributen für die Rolladendevices)&lt;br /&gt;
|-&lt;br /&gt;
|room_... || ||Auflistung aller Rollläden, welche in den jeweiligen Räumen gefunden wurden, Bsp.: room_Schlafzimmer,Terrasse&lt;br /&gt;
|-&lt;br /&gt;
|state || ||Status des &amp;lt;ASC-Device&amp;gt; active, enabled, disabled&lt;br /&gt;
|-&lt;br /&gt;
|sunriseTimeWeHoliday|| on,off ||legt fest, ob das Rolladendevice das Attribut &#039;&#039;AutoShuttersControl_Time_Up_WE_Holiday&#039;&#039; beachtet oder nicht&lt;br /&gt;
|-&lt;br /&gt;
|userAttrList || rolled out ||Status der UserAttribute, welche an die Rollläden gesendet werden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Readings in den Rolllädendevices ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Bedeutung  &lt;br /&gt;
|-&lt;br /&gt;
|ASC_Time_DriveUp ||Sonnenaufgangszeit für das Rollo&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Time_DriveDown ||Sonnenuntergangszeit für das Rollo&lt;br /&gt;
|-&lt;br /&gt;
|ASC_ShuttersLastDrive ||Grund des letzten Fahrens vom Rolladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==set- und get-Befehle für das ASC-Device==&lt;br /&gt;
&lt;br /&gt;
=== set-Anweisungen ===&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Datentyp/&amp;lt;BR/&amp;gt;Wertebereich !! Beschreibung  &lt;br /&gt;
|-&lt;br /&gt;
|partyMode ||on, off ||aktiviert den globalen Partymodus. Siehe Reading &#039;&#039;partyMode&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|lockOut ||on, off ||aktiviert den globalen Aussperrschutz. Siehe Reading &#039;&#039;lockOut&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|renewSetSunriseSunsetTimer || || erneuert bei allen Rollläden die Zeiten für Sunset und Sunrise und setzt die internen Timer neu.&lt;br /&gt;
|-&lt;br /&gt;
|scanForShutters || ||sucht alle FHEM Devices mit dem Attribut &#039;&#039;AutoShuttersControl&#039;&#039; &#039;&#039;1&#039;&#039; oder &#039;&#039;2&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|sunriseTimeWeHoliday || on,off ||aktiviert/deaktiviert die Beachtung des Attributes &#039;&#039;AutoShuttersControl_Time_Up_WE_Holiday&#039;&#039; für Rollladen-Devices&lt;br /&gt;
|-&lt;br /&gt;
|createNewNotifyDev || ||Legt die interne Struktur für NOTIFYDEV neu an&lt;br /&gt;
|-&lt;br /&gt;
|selfDefence ||on, off||aktiviert/deaktiviert den Selbstschutz: wenn das Residents-Device &#039;&#039;absent&#039;&#039; meldet, &#039;&#039;selfDefence&#039;&#039; aktiv ist und ein Fenster im Haus noch offen steht, wird an diesem Fenster das Rollo runtergefahren&lt;br /&gt;
|-&lt;br /&gt;
|wiggle ||||bewegt einen Rollladen oder alle Rollläden (für Abschreckungszwecke bei der Alarmierung) um &#039;&#039;ASC_WiggleValue&#039;&#039;-%, und nach 1 Minute wieder zurück zur Ursprungsposition&lt;br /&gt;
|-&lt;br /&gt;
|||||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== get-Anweisungen ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| showShuttersInformations ||zeigt eine Übersicht der Automatik-Fahrzeiten&lt;br /&gt;
|-&lt;br /&gt;
| showNotifyDevsInformations ||zeigt eine Übersicht der abgelegten NOTIFYDEV Struktur. Dient zur Kontrolle&lt;br /&gt;
|}&lt;br /&gt;
== Attribute ==&lt;br /&gt;
{{Hinweis|Die Attributnamen haben sich teilweise geändert, nachfolgend ist noch ein Stand vor Modulversion 0.6.5.x wiedergegeben. Die aktuellen Benennungen sind der Commandref zu entnehmen.}}&lt;br /&gt;
{{Hinweis|In der commandref findet sich häufig die Schreibweise &amp;lt;code&amp;gt;ASC_BrightnessSensor Sensorname[:brightness [400:800]]&amp;lt;/code&amp;gt;. Dabei sind die Angaben in den eckigen Klammern optional. Dies müssen also nicht angegeben werden, stattdessen verwendet das Modul dann Standardwerte (siehe cref), die in der cref zu findenden Angaben entsprechen dabei den defaults. Werden Werte angegeben, sind die eckigen Klammern &#039;&#039;&#039;wegzulassen&#039;&#039;&#039;! Beispiel: &amp;lt;code&amp;gt;ASC_BrightnessSensor hm_motion_1 70:100&amp;lt;/code&amp;gt; würde das brightness-Reading des Sensors hm_motion_1 verwenden und einen morgendlichen Schwellenwert von 70 bzw. 100 für abends.}}&lt;br /&gt;
===Attribute direkt am ASC-Device ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Datentyp/&amp;lt;BR/&amp;gt;Wertebereich !! Default-Wert !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|ASC_antifreezeTemp || || ||Temperatur, ab welcher der Frostschutz greift und das Rollo nicht mehr fährt. Der letzte Fahrbefehl wird gespeichert&lt;br /&gt;
|-&lt;br /&gt;
|ASC_autoAstroModeEvening ||aktuell REAL, CIVIL, NAUTIC, ASTRONOMIC, HORIZON || || (in genau dieser Schreibweise)&lt;br /&gt;
|-&lt;br /&gt;
|ASC_autoAstroModeEveningHorizon || || || Höhe über Horizont, wenn beim Attribut &#039;&#039;AutoShuttersControl_autoAstroModeEvening&#039;&#039; &#039;&#039;HORIZON&#039;&#039; ausgewählt&lt;br /&gt;
|-&lt;br /&gt;
|ASC_autoAstroModeMorning ||aktuell REAL, CIVIL, NAUTIC, ASTRONOMIC, HORIZON || ||(in genau dieser Schreibweise)&lt;br /&gt;
|-&lt;br /&gt;
|ASC_autoAstroModeMorningHorizon || || ||Höhe über Horizont, wenn beim Attribut &#039;&#039;AutoShuttersControl_autoAstroModeMorning&#039;&#039; &#039;&#039;HORIZON&#039;&#039; ausgewählt&lt;br /&gt;
|-&lt;br /&gt;
|ASC_autoShuttersControlComfort ||on, off || ||aktiviert die Komfortfunktion. Bedeutet, dass ein Rollladen mit einem threestate (Drehgriff-) Sensor am Fenster beim Öffnen in die &amp;quot;Komfortposition&amp;quot; fährt. Diese wird beim Rollladendevice über das Attribut &#039;&#039;AutoShuttersControl_Pos_after_ComfortOpen&#039;&#039; eingestellt.&lt;br /&gt;
|- &lt;br /&gt;
|ASC_autoShuttersControlEvening ||on, off || ||ob Abends die Rollläden automatisch zeitgesteuert werden sollen&lt;br /&gt;
|-&lt;br /&gt;
|ASC_autoShuttersControlMorning ||on, off || ||ob Morgens die Rollläden automatisch zeitgesteuert werden sollen&lt;br /&gt;
|-&lt;br /&gt;
|ASC_temperatureReading || || ||Reading für die Außentemperatur&lt;br /&gt;
|-&lt;br /&gt;
|ASC_temperatureSensor || || ||Device für die Außentemperatur&lt;br /&gt;
|-&lt;br /&gt;
|ASC_timeUpHolidayDevice || || ||Device zur Urlaubserkennung oder Sonstiges / muss &#039;&#039;0&#039;&#039; oder &#039;&#039;1&#039;&#039; im Reading &#039;&#039;state&#039;&#039; beinhalten.&lt;br /&gt;
|-&lt;br /&gt;
|ASC_residentsDevice|| || ||Devicenamen des Residents-Device der obersten Ebene&lt;br /&gt;
|-&lt;br /&gt;
|ASC_residentsDeviceReading|| || ||Status Reading des Residents-Device der obersten Ebene&lt;br /&gt;
|-&lt;br /&gt;
|ASC_brightnessMinVal|| || ||minimaler Lichtwert, bei dem Schaltbedingungen noch geprüft werden sollen&lt;br /&gt;
|-&lt;br /&gt;
|ASC_brightnessMaxVal || || ||maximaler Lichtwert, bei dem Schaltbedingungen noch geprüft werden sollen&lt;br /&gt;
|-&lt;br /&gt;
|ASC_rainSensorDevice || || ||Device, welches bei Regen getriggert wird&lt;br /&gt;
|-&lt;br /&gt;
|ASC_rainSensorReading || || ||das ensprechende Reading zum Regendevice&lt;br /&gt;
|-&lt;br /&gt;
|ASC_rainSensorShuttersClosedPos || || ||Position in pct, welche der Rollladen bei Regen anfahren soll &lt;br /&gt;
|-&lt;br /&gt;
|ASC_shuttersDriveOffset  || || ||maximale zufällige Verzögerung in Sekunden bei der Berechnung der Fahrzeiten, &#039;&#039;0&#039;&#039; bedeutet keine Verzögerung&lt;br /&gt;
|-&lt;br /&gt;
|ASC_twilightDevice || || ||Device, welches Informationen zum Sonnenstand liefert, wird unter anderem für die Beschattung verwendet.&lt;br /&gt;
|-&lt;br /&gt;
|ASC_expert || || ||bei &#039;&#039;1&#039;&#039; werden erweiterte Informationen bezüglich des NotifyDevs unter &#039;&#039;set&#039;&#039; und &#039;&#039;get&#039;&#039; angezeigt&lt;br /&gt;
|-&lt;br /&gt;
| || || ||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Attribute in den Rolllädendevices===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Datentyp/&amp;lt;BR/&amp;gt;Wertebereich !! Default-Wert !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|ASC || 0, 1, 2|| ||0 = &amp;quot;kein Anlegen der Attribute beim ersten Scan bzw. keine Beachtung eines Fahrbefehles&amp;quot;,1 = &amp;quot;Inverse oder Rollo - Bsp.: Rollo Oben 0, Rollo Unten 100 und der Befehl zum prozentualen Fahren ist position&amp;quot;,2 = &amp;quot;Homematic Style - Bsp.: Rollo Oben 100, Rollo Unten 0 und der Befehl zum prozentualen Fahren ist pct&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Antifreeze || soft, am, pm, hard, off|| ||Frostschutz, wenn &#039;&#039;soft&#039;&#039; fährt der Rollladen in die &#039;&#039;ASC_Antifreeze_Pos&#039;&#039;, bei &#039;&#039;hard/am/pm&#039;&#039; wird gar nicht oder innerhalb der entsprechenden Tageszeit nicht gefahren&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Antifreeze_Pos || || ||Position, die angefahren werden soll, wenn der Fahrbefehl komplett schließen lautet, aber der Frostschutz aktiv ist&lt;br /&gt;
|-&lt;br /&gt;
|ASC_AutoAstroModeEvening ||REAL, CIVIL, NAUTIC, ASTRONOMIC, HORIZON || ||aktuell REAL,CIVIL,NAUTIC,ASTRONOMIC&lt;br /&gt;
|-&lt;br /&gt;
|ASC_AutoAstroModeEveningHorizon || || ||Höhe über Horizont, wenn beim Attribut &#039;&#039;ASC_autoAstroModeEvening&#039;&#039; &#039;&#039;HORIZON&#039;&#039; ausgewählt ist&lt;br /&gt;
|-&lt;br /&gt;
|ASC_AutoAstroModeMorning ||REAL, CIVIL, NAUTIC, ASTRONOMIC, HORIZON || ||aktuell REAL,CIVIL,NAUTIC,ASTRONOMIC&lt;br /&gt;
|-&lt;br /&gt;
|ASC_AutoAstroModeMorningHorizon || || ||Höhe über Horizont, wenn beim Attribut &#039;&#039;ASC_autoAstroModeMorning&#039;&#039; &#039;&#039;HORIZON&#039;&#039; ausgewählt ist&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Closed_Pos || || ||in 10er Schritten von 0 bis 100,default Vorgabe ist abhängig vom Attribut &#039;&#039;ASC&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Down || astro, time, brightness || ||bei &#039;&#039;astro&#039;&#039; wird Sonnenuntergang berechnet, bei &#039;&#039;time&#039;&#039; wird der Wert aus &#039;&#039;ASC_Time_Down_Early&#039;&#039; als Fahrzeit verwendet und bei &#039;&#039;brightness&#039;&#039; muss &#039;&#039;ASC_Time_Down_Early&#039;&#039; und &#039;&#039;ASC_Time_Down_Late&#039;&#039; korrekt gesetzt werden. Der Timer läuft dann nach &#039;&#039;ASC_Time_Down_Late&#039;&#039;-Zeit,es wird aber in der Zeit zwischen &#039;&#039;ASC_Time_Down_Early&#039;&#039; und &#039;&#039;ASC_Time_Down_Late&#039;&#039; geschaut, ob die als Attribut im Moduldevice hinterlegte &#039;&#039;ASC_brightnessMinVal&#039;&#039; erreicht wurde. Wenn ja, wird der Rolladen runter gefahren&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Mode_Down ||always, home, absent, off || ||wann darf die Automatik herunterfahren. immer, niemals oder bei Abwesenheit des Roommate (ist kein Roommate und &#039;&#039;absent&#039;&#039; eingestellt, wird gar nicht gesteuert)&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Mode_Up ||always, home, absent, off || ||wann darf die Automatik hochfahren. immer, niemals oder bei Abwesenheit des Roommate (ist kein Roommate und &#039;&#039;absent&#039;&#039; eingestellt, wird gar nicht gesteuert)&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Drive_Offset || || ||maximale zufällige Verzögerung in Sekunden bei der Berechnung der Fahrzeiten, &#039;&#039;0&#039;&#039; bedeutet sofort, &#039;&#039;-1&#039;&#039; bedeutet, dass das gleichwertige Attribut aus dem ASC-Device ausgewertet werden soll&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Open_Pos || || ||in 10er-Schritten von 0 bis 100, default Vorgabe ist abhängig vom Attribut &#039;&#039;ASC&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Partymode || on, off || ||schaltet den Partymodus an oder aus. Wird dann am ASC Device &#039;&#039;set &amp;lt;ASC-DEVICE&amp;gt; partyMode on&#039;&#039; geschaltet, werden alle Fahrbefehle an den Rollläden, welche das Attribut auf &#039;&#039;on&#039;&#039; haben, zwischengespeichert und erst später ausgeführt&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Pos_Reading || || ||Name des Readings, welches die Position des Rollladen in Prozent angibt. Wird bei unbekannten Device-Typen auch als &#039;&#039;set&#039;&#039; Befehl zum Fahren verwendet&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Pos_after_ComfortOpen || || ||in 10er-Schritten von 0 bis 100, default Vorgabe ist abhängig vom Attribut &#039;&#039;ASC&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Roommate_Reading || || ||Reading des Roommate-Device, welches den Status wieder gibt&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Roommate_Device || || ||mit Komma getrennte Namen des/der Roommate-Device/s welche den/die Bewohner des Rollladen-Raumes wiedergibt. Macht nur Sinn in Schlaf- oder Kinderzimmern&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Time_Down_Early || || ||Sunset früheste Zeit zum Runterfahren&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Time_Down_Late || || ||Sunset späteste Zeit zum Runterfahren&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Time_Up_Early || || ||Sunrise früheste Zeit zum Hochfahren&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Time_Up_Late || || ||Sunrise späteste Zeit zum Hochfahren&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Time_Up_WE_Holiday || || ||Sunrise früheste Zeit zum Hochfahren am Wochenende und/oder Urlaub (holiday2we wird beachtet).&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Up || astro, time, brightness || ||bei &#039;&#039;astro&#039;&#039; wird Sonnenaufgang berechnet, bei &#039;&#039;time&#039;&#039; wird der Wert aus &#039;&#039;ASC_Time_Up_Early&#039;&#039; als Fahrzeit verwendet und bei &#039;&#039;brightness&#039;&#039; müssen &#039;&#039;ASC_Time_Up_Early&#039;&#039; und &#039;&#039;ASC_Time_Up_Late&#039;&#039; korrekt gesetzt werden. Der Timer läuft dann nach &#039;&#039;ASC_Time_Up_Late&#039;&#039;-Zeit, es wird aber in der Zeit zwischen &#039;&#039;ASC_Time_Up_Early&#039;&#039; und &#039;&#039;ASC_Time_Up_Late&#039;&#039; geschaut, ob die als Attribut im Moduldevice hinterlegte &#039;&#039;ASC_brightnessMinVal&#039;&#039; erreicht wurde. Wenn ja, wird der Rolladen runter gefahren&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Ventilate_Pos || || ||in 10er-Schritten von 0 bis 100, default Vorgabe ist abhängig vom Attribut &#039;&#039;ASC&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Ventilate_Window_Open || || ||auf lüften, wenn das Fenster gekippt/geöffnet wird und aktuelle Position unterhalb der Lüften-Position ist&lt;br /&gt;
|-&lt;br /&gt;
|ASC_WindowRec || || ||Name des Fensterkontakts, an welchen Fenster der Rollladen angebracht ist. Sein Reading &#039;&#039;state&#039;&#039; muss die Werte &#039;&#039;open&#039;&#039;, &#039;&#039;closed&#039;&#039; oder &#039;&#039;tilted&#039;&#039; enthalten.&lt;br /&gt;
|-&lt;br /&gt;
|ASC_WindowRec_subType || || ||Typ des verwendeten Fensterkontakts: &#039;&#039;twostate&#039;&#039; (optisch oder magnetisch) oder &#039;&#039;threestate&#039;&#039; (Drehgriffkontakt)&lt;br /&gt;
|-&lt;br /&gt;
|ASC_LockOut || soft, hard || ||stellt entsprechend den Aussperrschutz ein. Bei global aktiven Aussperrschutz (&#039;&#039;set ASC-Device lockOut soft&#039;&#039;) und einem Fensterkontakt &#039;&#039;open&#039;&#039; bleibt dann der Rolladen oben. Dies gilt nur bei Steuerbefehle über das ASC-Modul. Stellt man global auf &#039;&#039;hard&#039;&#039;, wird bei entsprechender Möglichkeit versucht, den Rollladen hardwareseitig zu blockieren. Dann ist auch ein Fahren über die Taster nicht mehr möglich.&lt;br /&gt;
|-&lt;br /&gt;
|ASC_LockOutCmd || inhibit, blocked || ||set Befehl für das Rolladen-Device zum Sperren per Hardware. Der Befehl wird verwendet, wenn &#039;&#039;ASC_LockOut&#039;&#039; auf &#039;&#039;hard&#039;&#039; gesetzt ist&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Self_Defense_Exclude || on, off || ||bei &#039;&#039;on&#039;&#039; wird dieser Rolladen bei aktiven &#039;&#039;selfDefence&#039;&#039; und offenen Fenster nicht runter gefahren, wenn Residents absent ist&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_Brightness_Sensor || || ||Sensor-Device, welches für die Lichtwerte verwendet wird. ACHTUNG! Findet auch Verwendung bei ASC_Down - brightness&lt;br /&gt;
|-&lt;br /&gt;
|ASC_BrightnessMinVal || || ||minimaler Lichtwert, bei dem Schaltbedingungen noch geprüft werden sollen / wird der Wert von &#039;&#039;-1&#039;&#039; nicht geändert, so wird automatisch der Wert aus dem Moduldevice genommen&lt;br /&gt;
|-&lt;br /&gt;
|ASC_BrightnessMaxVal || || ||maximaler Lichtwert, bei dem Schaltbedingungen noch geprüft werden sollen / wird der Wert von &#039;&#039;-1&#039;&#039; nicht geändert, so wird automatisch der Wert aus dem Moduldevice genommen&lt;br /&gt;
|-&lt;br /&gt;
|ASC_ShuttersPlace || window, terrace || ||wenn dieses Attribut auf &#039;&#039;terrace&#039;&#039; gesetzt ist und das Residents-Device in den Status &#039;&#039;gone&#039;&#039; geht und &#039;&#039;selfDefence&#039;&#039; aktiv ist, wird das Rollo geschlossen&lt;br /&gt;
|-  &lt;br /&gt;
|ASC_WiggleValue || || ||Wert, um welchen sich die Position des Rollladens bei &#039;&#039;Wiggle&#039;&#039; ändern soll &lt;br /&gt;
|-&lt;br /&gt;
|ASC_BlockingTime_afterManual || || ||Wartezeit in Sekunden, die die Automatik nach einer manuellen Fahrt aussetzen soll&lt;br /&gt;
|-&lt;br /&gt;
|ASC_BlockingTime_beforNightClose || || ||Vorgabezeit in Sekunden, innerhalb derer vor dem nächtlichen Schließen keine Öffnen-Fahrt mehr ausgeführt werden soll&lt;br /&gt;
|-&lt;br /&gt;
|ASC_BlockingTime_beforDayOpen || || ||Vorgabezeit in Sekunden, innerhalb derer vor dem morgendlichen Öffnen keine Schließen-Fahrt mehr ausgeführt werden soll&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_Direction || || ||Position in Grad, auf der das Fenster liegt - genau Osten wäre 90, Süden 180 und Westen 270&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_Pos || || ||Position des Rollladens für die Beschattung&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_Angle_Left || || ||Vorlaufwinkel im Bezug zum Fenster, ab wann abgeschattet wird. Beispiel: Fenster 180° - 85° ==&amp;gt; ab Sonnenpos. 95° wird abgeschattet&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_Angle_Right || || ||Nachlaufwinkel im Bezug zum Fenster, bis wann abgeschattet wird. Beispiel: Fenster 180° + 85° ==&amp;gt; bis Sonnenpos. 265° wird abgeschattet&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_Mode || || ||absent,always,off,home / Vorgabe, wann Beschattungsaktionen durchzuführen sind&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_StateChange_Sunny || || ||Brightness Wert ab welchen Beschattung statt finden soll, immer in Abhängikkeit der anderen einbezogenden Sensorwerte&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_StateChange_Cloudy || || ||Brightness Wert ab welchen die Beschattung aufgehoben werden soll, immer in Abhängikkeit der anderen einbezogenden Sensorwerte&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_Min_Elevation || || ||ab welcher Höhe des Sonnenstandes soll beschattet werden, immer in Abhängikkeit der anderen einbezogenden Sensorwerte&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_Min_OutsideTemperature || || ||ab welcher Temperatur soll Beschattet werden, immer in Abhängikkeit der anderen einbezogenden Sensorwerte&lt;br /&gt;
|-&lt;br /&gt;
|ASC_Shading_WaitingPeriod || || ||wie viele Sekunden soll gewartet werden bevor eine weitere Auswertung der Sensordaten für die Beschattung statt finden soll&lt;br /&gt;
|-&lt;br /&gt;
|ASC_PrivacyDownTime_beforNightClose || || ||wie viele Sekunden vor dem abendlichen schlie&amp;amp;zlig;en soll der Rollladen in die Sichtschutzposition fahren, -1 bedeutet das diese Funktion unbeachtet bleiben soll&lt;br /&gt;
|-&lt;br /&gt;
|ASC_PrivacyDown_Pos || || ||Position den Rollladens für den Sichtschutz&lt;br /&gt;
|-&lt;br /&gt;
| || || ||&lt;br /&gt;
| || || ||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||    &lt;br /&gt;
|-  &lt;br /&gt;
| || || ||&lt;br /&gt;
|-&lt;br /&gt;
| || || ||        &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Hilfsmittel ==&lt;br /&gt;
{{Hinweis|Die Device-Namen sind auf die eigene Installation anzupassen.}}&lt;br /&gt;
&lt;br /&gt;
=== Interne Übersicht ===&lt;br /&gt;
[[Bild:ASC Overview.JPG|thumb|right|weblink - Beispiel]]&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:65%;word-break: break-all;word-wrap: break-word;&amp;quot;&amp;gt;&lt;br /&gt;
 define ASC_Jalousie_Info weblink htmlCode {AutoShuttersControl::GetShuttersInformation($defs{&#039;JalousieControl&#039;})}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|Codezeilen sind im [[Import von Code Snippets|RAW]]-Format.}}&lt;br /&gt;
&lt;br /&gt;
=== readingsGroup für Level ===&lt;br /&gt;
&lt;br /&gt;
{{Randnotiz|RNTyp=g|RNText= Stand 2019-05-03&lt;br /&gt;
* Erfolgreich getestet mit Homematic Devices, Beta-User&lt;br /&gt;
* Die Farbgebung entspricht dem Standard, wenn unter dem Style f18 der Farbpreset &#039;&#039;light&#039;&#039; gewählt wird.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:65%;word-wrap: break-word;&amp;quot;&amp;gt;defmod rg_ASC_Rolllaeden_Level readingsGroup &amp;lt;Gerät&amp;gt;,&amp;lt;Stand&amp;gt;,&amp;lt;Schliessen bis&amp;gt;,&amp;lt;Öffnen auf&amp;gt;,&amp;lt;Beschattung&amp;gt;,&amp;lt;Komfort&amp;gt;,&amp;lt;Lüften&amp;gt;,&amp;lt;Privacy&amp;gt; (Rollladen_.*|Jalousie_.*)..:level,!?ASC_Closed_Pos,!?ASC_Open_Pos,!?ASC_Shading_Pos,!?ASC_ComfortOpen_Pos,!?ASC_Ventilate_Pos,!?ASC_PrivacyDown_Pos&lt;br /&gt;
attr rg_ASC_Rolllaeden_Level commands {level =&amp;gt; &#039;pct:selectnumbers,0,5,100,0,lin&#039;,\&lt;br /&gt;
ASC_Closed_Pos =&amp;gt; &#039;ASC_Closed_Pos:selectnumbers,0,5,100,0,lin&#039;,\&lt;br /&gt;
ASC_Open_Pos =&amp;gt; &#039;ASC_Open_Pos:selectnumbers,0,5,100,0,lin&#039;,\&lt;br /&gt;
ASC_Shading_Pos =&amp;gt; &#039;ASC_Shading_Pos:selectnumbers,0,5,100,0,lin&#039;,\&lt;br /&gt;
ASC_Ventilate_Pos =&amp;gt; &#039;ASC_Ventilate_Pos:selectnumbers,0,5,100,0,lin&#039;,\&lt;br /&gt;
ASC_ComfortOpen_Pos =&amp;gt; &#039;ASC_ComfortOpen_Pos:selectnumbers,0,5,100,0,lin&#039;,\&lt;br /&gt;
ASC_PrivacyDown_Pos =&amp;gt; &#039;ASC_PrivacyDown_Pos:selectnumbers,0,5,100,0,lin&#039;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== readingsGroup für Zeiten ===&lt;br /&gt;
[[Bild:ReadingsGroup ASC times.png|thumb|right|ReadingsGroup - Zeitenbeispiel]]&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:65%;word-wrap: break-word;&amp;quot;&amp;gt;defmod rg_ASC_Rolllaeden_Times readingsGroup &amp;lt;Gerät&amp;gt;,&amp;lt;Position&amp;gt;,&amp;lt;Time_Up_Early&amp;gt;,&amp;lt;Time_Up_Late&amp;gt;,&amp;lt;Time_Up_WE/Hol&amp;gt;,&amp;lt;Time_Down_Early&amp;gt;,&amp;lt;Time_Down_Late&amp;gt;,&amp;lt;Mode_Down&amp;gt;,&amp;lt;Mode_Up&amp;gt; \&lt;br /&gt;
 (.*Rollo.*|.*Rollladen|Jalousie_.*):level,?ASC_Time_Up_Early,?ASC_Time_Up_Late,?ASC_Time_Up_WE_Holiday,?ASC_Time_Down_Early,?ASC_Time_Down_Late,?ASC_Mode_Down,?ASC_Mode_Up&lt;br /&gt;
attr rg_ASC_Rolllaeden_Times commands {level =&amp;gt; &#039;pct:0,10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100&#039;, \&lt;br /&gt;
 ASC_Time_Down_Early =&amp;gt; &#039;ASC_Time_Down_Early:15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00&#039;, \&lt;br /&gt;
 ASC_Time_Down_Late  =&amp;gt; &#039;ASC_Time_Down_Late:19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30&#039;, \&lt;br /&gt;
 ASC_Time_Up_WE_Holiday =&amp;gt; &#039;ASC_Time_Up_WE_Holiday:06:00,06:15,06:30,06:45,07:00,07:15,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00&#039;,\&lt;br /&gt;
 ASC_Time_Up_Early =&amp;gt; &#039;ASC_Time_Up_Early:05:00,05:05,05:30,05:55,06:00,06:15,06:30,06:45,07:00,07:15,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00&#039;,  \&lt;br /&gt;
 ASC_Time_Up_Late =&amp;gt; &#039;ASC_Time_Up_Late:06:00,06:15,06:30,06:45,07:00,07:15,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00&#039;, \&lt;br /&gt;
 ASC_Mode_Down =&amp;gt; &#039;ASC_Mode_Down:always,absent,off&#039;, \&lt;br /&gt;
 ASC_Mode_Up =&amp;gt; &#039;ASC_Mode_Up:always,absent,off&#039; }&lt;br /&gt;
attr rg_ASC_Rolllaeden_Times room Rollladen&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:ASC RG Zeiten HM ZWave Siro.png|thumb|right|ReadingsGroup - CUL_HM+ZWave+Siro mit widgets]]Neue Version mit time-Widgets und pct/dim/position-widget (5-er Schritte), passend für CUL_HM, ZWave und Siro-Geräte:&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:65%;word-wrap: break-word;&amp;quot;&amp;gt;defmod rg_ASC_Rolllaeden_Times readingsGroup &amp;lt;Gerät&amp;gt;,&amp;lt;Stand&amp;gt;,&amp;lt;Time_Up_Early  &amp;gt;,&amp;lt;Time_Up_WE  &amp;gt;,&amp;lt;Time_Up_Late  &amp;gt;,&amp;lt;Time_Down_Early&amp;gt;,&amp;lt;Time_Down_Late&amp;gt;,&amp;lt;Mode_Down&amp;gt;,&amp;lt;Mode_Up&amp;gt; (Rollo_.*|Jalousie_.*)..:(level|dim|position),!?ASC_Time_Up_Early,!?ASC_Time_Up_WE_Holiday,!?ASC_Time_Up_Late,!?ASC_Time_Down_Early,!?ASC_Time_Down_Late,!?ASC_Mode_Down,!?ASC_Mode_Up&lt;br /&gt;
attr rg_ASC_Rolllaeden_Times commands {level =&amp;gt; &#039;pct:selectnumbers,0,5,100,0,lin&#039;, \&lt;br /&gt;
dim =&amp;gt; &#039;dim:selectnumbers,0,5,99,0,lin&#039;,\&lt;br /&gt;
position =&amp;gt; &#039;pct:selectnumbers,0,5,99,0,lin&#039;,\&lt;br /&gt;
ASC_Mode_Down =&amp;gt; &#039;ASC_Mode_Down:always,absent,off&#039;,\&lt;br /&gt;
ASC_Mode_Up =&amp;gt; &#039;ASC_Mode_Up:always,absent,off&#039;,\&lt;br /&gt;
ASC_Time_Down_Early =&amp;gt; &#039;ASC_Time_Down_Early:time&#039;, \&lt;br /&gt;
ASC_Time_Down_Late  =&amp;gt; &#039;ASC_Time_Down_Late:time&#039;,\&lt;br /&gt;
ASC_Time_Up_Early =&amp;gt; &#039;ASC_Time_Up_Early:time&#039;, \&lt;br /&gt;
ASC_Time_Up_Late =&amp;gt;&#039;ASC_Time_Up_Late:time&#039;,\&lt;br /&gt;
ASC_Time_Up_WE_Holiday =&amp;gt;&#039;ASC_Time_Up_WE_Holiday:time&#039;}&lt;br /&gt;
attr rg_ASC_Rolllaeden_Times room Rollladen&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  readingsGroup für die Beschattung ===&lt;br /&gt;
[[Bild:ReadingsGroup ASC shading.png|thumb|right|ReadingsGroup - Beschattungsbeispiel]]&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:65%;word-wrap: break-word;&amp;quot;&amp;gt;&lt;br /&gt;
defmod rg_ASC_Rolllaeden_Shading readingsGroup &amp;lt;Gerät&amp;gt;,&amp;lt;Modus&amp;gt;,&amp;lt;Position&amp;gt;,&amp;lt;Richtung&amp;gt;,&amp;lt;°links&amp;gt;,&amp;lt;°rechts&amp;gt;,&amp;lt;Elevation&amp;gt;,&amp;lt;Sunny&amp;gt;,&amp;lt;Cloudy&amp;gt;,&amp;lt;Min Temp&amp;gt; (Rollo|Jalousie)_.*..:!?ASC_Shading_Mode,!?ASC_Shading_Pos,!?ASC_Shading_Direction,!?ASC_Shading_Angle_Left,!?ASC_Shading_Angle_Right,!?ASC_Shading_MinMax_Elevation,!?ASC_Shading_StateChange_Sunny,!?ASC_Shading_StateChange_Cloudy,!?ASC_Shading_Min_OutsideTemperature&lt;br /&gt;
&lt;br /&gt;
attr rg_ASC_Rolllaeden_Shading alias Rollläden: Beschattung&lt;br /&gt;
attr rg_ASC_Rolllaeden_Shading commands {ASC_Shading_Pos =&amp;gt; &#039;ASC_Shading_Pos:knob,min:0,max:100,width:50,height:50,fgColor:#FF9900,bgColor:#CCCCCC,step:5,lineCap:round&#039;,\&lt;br /&gt;
ASC_Shading_Mode =&amp;gt; &#039;ASC_Shading_Mode:always,home,absent,off&#039;,\&lt;br /&gt;
ASC_Shading_Direction =&amp;gt; &#039;ASC_Shading_Direction:knob,min:0,max:360,width:50,height:50,fgColor:#FF9900,bgColor:#CCCCCC,step:1,cursor:true,lineCap:round&#039;,\&lt;br /&gt;
ASC_Shading_Angle_Left =&amp;gt; &#039;ASC_Shading_Angle_Left:knob,min:0,max:85,angleArc:85,rotation:anticlockwise,width:50,height:50,fgColor:#FF9900,bgColor:#CCCCCC,step:5,lineCap:round,angleOffset:270&#039;,\&lt;br /&gt;
ASC_Shading_Angle_Right =&amp;gt; &#039;ASC_Shading_Angle_Right:knob,min:0,max:85,angleArc:85,width:50,height:50,fgColor:#FF9900,bgColor:#CCCCCC,step:5,lineCap:round,&#039;,\&lt;br /&gt;
ASC_Shading_MinMax_Elevation =&amp;gt; &#039;ASC_Shading_MinMax_Elevation:knob,min:0,max:35,width:50,height:50,fgColor:#FF9900,bgColor:#CCCCCC,step:1,lineCap:round,angleArc:120,angleOffset:270&#039;,\&lt;br /&gt;
ASC_Shading_StateChange_Sunny =&amp;gt; &#039;ASC_Shading_StateChange_Sunny:knob,min:100,max:1200,angleArc:85,rotation:anticlockwise,width:50,height:50,fgColor:#FF9900,bgColor:#CCCCCC,step:20,lineCap:round,angleOffset:270&#039;,\&lt;br /&gt;
ASC_Shading_StateChange_Cloudy =&amp;gt; &#039;ASC_Shading_StateChange_Cloudy:knob,min:100,max:1200,angleArc:85,width:50,height:50,fgColor:#FF9900,bgColor:#CCCCCC,step:20,lineCap:round,&#039;,\&lt;br /&gt;
ASC_Shading_Min_OutsideTemperature =&amp;gt; &#039;ASC_Shading_Min_OutsideTemperature:knob,min:5,max:30,width:50,height:50,fgColor:#FF9900,bgColor:#CCCCCC,step:0.5,lineCap:round,angleArc:120,angleOffset:270&#039;}&lt;br /&gt;
attr rg_ASC_Rolllaeden_Shading room Rollladen&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Anderes {{Link2Forum|Topic=99980|Message=946357|LinkText=Foren-Beispiel}} für eine RG zu Beschattung (für V. 0.6.x):&lt;br /&gt;
[[Bild:ReadingsGroup ASC shading2.png|thumb|right|ReadingsGroup - Beschattungsbeispiel]]&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:65%;word-wrap: break-word;&amp;quot;&amp;gt;&lt;br /&gt;
defmod rg_ASC_Shading readingsGroup &amp;lt;Gerät&amp;gt;,&amp;lt;Grad&amp;gt;,&amp;lt;Position&amp;gt;,&amp;lt;Mode&amp;gt;,&amp;lt;Links&amp;gt;,&amp;lt;Rechts&amp;gt;,&amp;lt;Wait&amp;gt;,&amp;lt;ShadeIn&amp;gt;,&amp;lt;ShadeOut&amp;gt;,&amp;lt;Elevation&amp;gt;,&amp;lt;Temperature&amp;gt;,&amp;lt;Device&amp;gt;\&lt;br /&gt;
(Rollo_.*|Jalousie.*):!?ASC_Shading_Direction,!?ASC_Shading_Pos,!?ASC_Shading_Mode,!?ASC_Shading_Angle_Left,!?ASC_Shading_Angle_Right,!?ASC_Shading_WaitingPeriod,!?ASC_Shading_StateChange_Sunny,!?ASC_Shading_StateChange_Cloudy,!?ASC_Shading_MinMax_Elevation,!?ASC_Shading_Min_OutsideTemperature,!?ASC_BrightnessSensor\&lt;br /&gt;
&lt;br /&gt;
attr rg_ASC_Shading commands {ASC_Shading_Direction =&amp;gt; &#039;ASC_Shading_Direction:129,255,309&#039;,\&lt;br /&gt;
ASC_Shading_Pos =&amp;gt; &#039;ASC_Shading_Pos:selectnumbers,0,5,100,0,lin&#039;,\&lt;br /&gt;
ASC_Shading_Mode =&amp;gt; &#039;ASC_Shading_Mode:absent,always,off,home&#039;,\&lt;br /&gt;
ASC_Shading_Angle_Left =&amp;gt; &#039;ASC_Shading_Angle_Left:selectnumbers,0,5,100,0,lin&#039;,\&lt;br /&gt;
ASC_Shading_Angle_Right =&amp;gt; &#039;ASC_Shading_Angle_Right:selectnumbers,0,5,100,0,lin&#039;,\&lt;br /&gt;
ASC_Shading_WaitingPeriod =&amp;gt; &#039;ASC_Shading_WaitingPeriod:selectnumbers,0,60,1200,0,lin&#039;,\&lt;br /&gt;
ASC_Shading_StateChange_Sunny =&amp;gt; &#039;ASC_Shading_StateChange_Sunny:selectnumbers,0,20,1000,0,lin&#039;,\&lt;br /&gt;
ASC_Shading_StateChange_Cloudy =&amp;gt; &#039;ASC_Shading_StateChange_Cloudy:selectnumbers,0,20,1000,0,lin&#039;,\&lt;br /&gt;
ASC_Shading_MinMax_Elevation =&amp;gt;\&lt;br /&gt;
&#039;ASC_Shading_Min_Elevation:selectnumbers,0,1,40,0,lin&#039; ,\&lt;br /&gt;
ASC_Shading_Min_OutsideTemperature =&amp;gt;\&lt;br /&gt;
&#039;ASC_Shading_Min_OutsideTemperature:selectnumbers,0,1,30,0,lin&#039;}&lt;br /&gt;
attr rg_ASC_Shading room Rollladen&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  readingsGroup für FIBARO Roller Shutter FGR-222 Devices ===&lt;br /&gt;
{{Randnotiz|RNTyp=g|RNText=Getestet von majestro84, Stand 2019-01-28.&lt;br /&gt;
* https://forum.fhem.de/index.php/topic,92628.msg897099.html#msg897099&lt;br /&gt;
* Die Farbgebung entspricht dem Standard, wenn unter dem Style f18 der Farbpreset &#039;&#039;dark&#039;&#039; gewählt wird}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:ASC Jalousien Times.JPG|thumb|right|Beispiel]]&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:65%;word-break: break-all;word-wrap: break-word;&amp;quot;&amp;gt;define ASC_Jalousien_Times readingsGroup &amp;lt;Gerät&amp;gt;,&amp;lt;Stand&amp;gt;,&amp;lt;Time_Up_Early&amp;gt;,&amp;lt;Time_Up_WE&amp;gt;,&amp;lt;Time_Up_Late&amp;gt;,&amp;lt;Time_Down_Early&amp;gt;,&amp;lt;Time_Down_Late&amp;gt;,&amp;lt;Mode_Down&amp;gt;,&amp;lt;Mode_Up&amp;gt;,&amp;lt;PartyMode&amp;gt;,&amp;lt;LockOut&amp;gt; (.*_Jalousie.*):position,?ASC_Time_Up_Early,?ASC_Time_Up_WE_Holiday,?ASC_Time_Up_Late,?ASC_Time_Down_Early,?ASC_Time_Down_Late,?ASC_Mode_Down,?ASC_Mode_Up,?ASC_Partymode,?ASC_LockOut&lt;br /&gt;
&lt;br /&gt;
 attr ASC_Jalousien_Times commands {position =&amp;gt; &#039;dim:0,10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,99&#039;,&lt;br /&gt;
 ASC_Mode_Down =&amp;gt; &#039;ASC_Mode_Down:always,absent,off&#039;,&lt;br /&gt;
 ASC_Mode_Up =&amp;gt; &#039;ASC_Mode_Up:always,absent,off&#039;,&lt;br /&gt;
 ASC_Partymode =&amp;gt; &#039;ASC_Partymode:on,off&#039;,&lt;br /&gt;
 ASC_LockOut =&amp;gt; &#039;ASC_LockOut:soft,hard,off&#039;,&lt;br /&gt;
 ASC_Time_Down_Early =&amp;gt; &#039;ASC_Time_Down_Early:15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00&#039;, &lt;br /&gt;
 ASC_Time_Down_Late  =&amp;gt; &#039;ASC_Time_Down_Late:20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30&#039;,&lt;br /&gt;
 ASC_Time_Up_Early =&amp;gt; &#039;ASC_Time_Up_Early:05:00,05:05,05:30,05:45,06:00,06:15,06:30,06:45,07:00,07:15,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00&#039;,&lt;br /&gt;
 ASC_Time_Up_Late =&amp;gt;&#039;ASC_Time_Up_Late:06:00,06:15,06:30,06:45,07:00,07:15,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00&#039;,&lt;br /&gt;
 ASC_Time_Up_WE_Holiday =&amp;gt; &#039;ASC_Time_Up_WE_Holiday:06:00,06:15,06:30,06:45,07:00,07:15,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00&#039;}&lt;br /&gt;
 attr ASC_Jalousien_Times room Jalousien&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:ASC Jalousien Level.JPG|thumb|right|Beispiel]]&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:65%;word-break: break-all;word-wrap: break-word;&amp;quot;&amp;gt; define Jalousien_Level readingsGroup &amp;lt;Gerät&amp;gt;,&amp;lt;Closed_Pos&amp;gt;,&amp;lt;Open_Pos&amp;gt;,&amp;lt;Comfort_Pos&amp;gt;,&amp;lt;Ventilate_Pos&amp;gt;,&amp;lt;PrivacyDown_Pos&amp;gt;,&amp;lt;Shading_Pos&amp;gt; (.*_Jalousie.*):?ASC_Closed_Pos,?ASC_Open_Pos,?ASC_ComfortOpen_Pos,?ASC_Ventilate_Pos,?ASC_PrivacyDown_Pos,?ASC_Shading_Pos&lt;br /&gt;
 attr Jalousien_Level commands { ASC_Closed_Pos =&amp;gt; &#039;ASC_Closed_Pos:0,10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,99&#039;,&lt;br /&gt;
 ASC_Open_Pos =&amp;gt; &#039;ASC_Open_Pos:0,10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,99&#039;,&lt;br /&gt;
 ASC_ComfortOpen_Pos =&amp;gt; &#039;ASC_ComfortOpen_Pos:0,10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,99&#039;,&lt;br /&gt;
 ASC_Ventilate_Pos =&amp;gt; &#039;ASC_Ventilate_Pos:0,10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,99&#039;,&lt;br /&gt;
 ASC_PrivacyDown_Pos =&amp;gt; &#039;ASC_PrivacyDown_Pos:0,10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,99&#039;,&lt;br /&gt;
 ASC_Shading_Pos =&amp;gt; &#039;ASC_Shading_Pos:0,10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,99&#039;}&lt;br /&gt;
 attr Jalousien_Level room Jalousien&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einrichtungsbeispiel ==&lt;br /&gt;
=== Zielsetzung und Vorgaben ===&lt;br /&gt;
Es sollen alle Rollläden und Jalousien in einem Haus innerhalb bestimmter zeitlicher Grenzen Morgens und Abends sonnenstandsabhängig gefahren werden, an den Wochenenden und an Ferientagen soll etwas später geöffnet werden. Es sind Tür- und Fensterkontakte vorhanden (Türkontakte: twoState, Fensterkontakte: threeState), wobei bei jeder Öffnung ein eventuell geschlossener Rollladen geöffnet werden soll. Bei allen Rollladenaktoren, Tür- und Fensterkontakten handelt es sich um CUL_HM-Geräte.&lt;br /&gt;
&lt;br /&gt;
=== Vorarbeiten ===&lt;br /&gt;
Im global-Device sind Angaben zu latitude und longitude vorhanden, holiday2we wie folgt&amp;lt;ref&amp;gt;&#039;&#039;ferien&#039;&#039; ist eine automatisiert erstellte holiday-Datei nach diesem {{Link2Forum|Topic=85759|Message=885883|LinkText=Foren-Beitrag}}.&amp;lt;/ref&amp;gt;:&lt;br /&gt;
 attr global holiday2we bw,ferien&lt;br /&gt;
Weitere Angaben benötigen wir zunächst nicht, die Festlegung eines Astro-Devices erfolgt hier erst im Rahmen der Beschattung. &lt;br /&gt;
Dann erfolgt das &#039;&#039;Define des ASC-Devices&#039;&#039; wie oben beschrieben:&lt;br /&gt;
&amp;lt;code&amp;gt;define Rollladenautomatik AutoShuttersControl&amp;lt;/code&amp;gt;&lt;br /&gt;
Folgen die einzubindenden Rollladenaktoren einem einheitlichen Namensschema, können diese sodann z.B. mit &lt;br /&gt;
 attr (Jalousie|Rollladen)_.* ASC 2&lt;br /&gt;
auf einen Rutsch mit dem passenden ASC-Typ gekennzeichnet werden. Dann verteilen wir mir &lt;br /&gt;
 set Rollladenautomatik scanForShutters&lt;br /&gt;
die nachfolgend weiter zu bearbeitenden Attribute.&lt;br /&gt;
=== Schließen morgens und abends ===&lt;br /&gt;
{{Randnotiz|RNTyp=g|RNText=Alternative: Fahren nach brightness:&lt;br /&gt;
Will man insgesamt oder nur an einzelnen Rollläden stattdessen helligkeitsgesteuert fahren, muß für jeden Rollladen ein Helligkeitssensor definiert und entweder zentral oder am einzelnen Rollladen jeweils ein Höchst- bzw. Mindestwert festgelegt werden (&#039;&#039;ASC_BrightnessMinVal&#039;&#039; etc.), bei dessen Überschreitung geöffnet bzw. Unterschreitung geschlossen werden soll.}}&lt;br /&gt;
==== Konfiguration des ASC-Devices ====&lt;br /&gt;
Da wir sonnenstandsabhängig Fahrzeiten wollen, legen wir erst einmal fest, dass dies morgens und abends berücksichtigt werden soll:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attr Rollladenautomatik ASC_autoAstroModeEvening CIVIL&lt;br /&gt;
attr Rollladenautomatik ASC_autoAstroModeMorning CIVIL&lt;br /&gt;
attr Rollladenautomatik ASC_autoShuttersControlEvening on&lt;br /&gt;
attr Rollladenautomatik ASC_autoShuttersControlMorning on&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Aus der Angabe &#039;&#039;CIVIL&#039;&#039; und den Vorgaben in den einzelnen Rollladen wird dabei mit Hilfe von [[SUNRISE_EL]] die effektive Fahrzeit berechnet, dort finden sich auch weitere Hinweise, zu den meisten anderen Optionen für die ersten beiden Attribute.&lt;br /&gt;
Bei allen Fensteröffnungen soll auf eine Lüften-Position gefahren werden, also schalten wir diese Funktion ebenfalls zentral an&amp;lt;ref&amp;gt;Sonst wird bei threeState-Sensoren nur bei &#039;&#039;tilted&#039;&#039; auf die in &#039;&#039;ASC_Ventilate_Pos&#039;&#039; gefahren.&amp;lt;/ref&amp;gt;:&lt;br /&gt;
 attr Rollladenautomatik ASC_autoShuttersControlComfort on &lt;br /&gt;
Zuletzt legen wir noch einen Temperatur-Sensor fest. Dieser wird beim Frostschutz sowie bei der Beschattung berücksichtigt.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attr Rollladenautomatik ASC_temperatureSensor Aussentemperatur_Nord&lt;br /&gt;
attr Rollladenautomatik ASC_temperatureReading temperature&lt;br /&gt;
attr Rollladenautomatik ASC_freezeTemp 3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tbd: &lt;br /&gt;
* Rain&lt;br /&gt;
* Wind&lt;br /&gt;
==== Konfiguration der Rollladendevices ====&lt;br /&gt;
===== Fahrzeiten =====&lt;br /&gt;
Zur Konfiguration der Fahrzeiten bietet es sich an, eine ReadingsGroup zu nutzen, wie unter [[#Hilfsmittel|Hilfsmittel]] dargestellt. Alternativ kann man die Zeiten auch manuell in den einzelnen Rollläden hinterlegen.&lt;br /&gt;
===== Bewohner =====&lt;br /&gt;
Wird ein Raum von einer oder mehreren bestimmten Person/en bewohnt oder gibt es ein Sammel-Gerät für mehrere Bewohner, kann dies mit den Attributen &#039;&#039;ASC_Roommate_Device&#039;&#039; und &#039;&#039;ASC_Roommate_Reading&#039;&#039; einem Rollladen zugeordnet werden. Ist einer der Bewohner &#039;&#039;asleep&#039;&#039;, wird morgens erst geöffnet, wenn auch der letzte Roommate nicht mehr &#039;&#039;asleep&#039;&#039; ist.&lt;br /&gt;
===== Fensterkontakte  =====&lt;br /&gt;
Dann werden ggf. vorhandene Fensterkontakte zugeordnet und der Typ festgelegt, wobei im Falle von threeState-Sensoren das übergreifende &#039;&#039;ASC_autoShuttersControlComfort&#039;&#039; beachtet wird, wobei dann bei vollstäniger Öffnung des Fensters auf den in &#039;&#039;ASC_ComfortOpen_Pos&#039;&#039; festgelegten Wert gefahren wird.&lt;br /&gt;
===== Frostschutz =====&lt;br /&gt;
Zuletzt können die Attribute &#039;&#039;ASC_Antifreeze&#039;&#039; und &#039;&#039;ASC_Antifreeze_Pos&#039;&#039; festgelegt werden, wenn die Frostschutzfunktion aktiviert werden soll.&lt;br /&gt;
=== Beschattung ===&lt;br /&gt;
==== Konfiguration des ASC-Devices ====&lt;br /&gt;
Benötigt werden Informationen zum Sonnenstand. Hierfür wird ein astro- oder twilight-Device benötigt. Ist ein solches definiert, wird dies - ggf. auch nach einem Neustart vom Modul automatisch erkannt und in das Attribut &#039;&#039;ASC_twilightDevice&#039;&#039; eingetragen. Wir legen daher zunächst ein entsprechendes Device an bzw. passen die Angabe ggf. an, wenn ein anderes als das eingetragene genutzt werden soll.&lt;br /&gt;
Weiter ist ein Temperatursensor für die Beschattung festzulegen (&#039;&#039;ASC_temperatureSensor.*&#039;&#039;-Attribute) wie bereits oben beschrieben.&lt;br /&gt;
&lt;br /&gt;
==== Konfiguration der Rollladendevices ====&lt;br /&gt;
Zum einen legt man einen Helligkeitssensor fest (&#039;&#039;ASC_Brightness_Sensor&#039;&#039; und &#039;&#039;ASC_Brightness_Reading&#039;&#039;). Dieser ist der eigentliche Trigger. Nur, wenn sich der Brightness Wert ändert, werden Azimut, Elevation, Temperatur und die Ein- und Ausfallswinkel ausgelesen und/oder berechnet und basierend auf diesen Werten entschieden ob shading in oder shading out stattfinden soll, die Schwellwerte werden in &#039;&#039;ASC_Shading_StateChange_Sunny&#039;&#039; (Beschattung soll eingeschaltet werden) und &#039;&#039;ASC_Shading_StateChange_Cloudy&#039;&#039; (Beschattung soll beendet werden) festgelegt, wobei immer nur gefahren wird, wenn auch alles andere - insbesondere die Mindesthöhe des Sonnenstands (&#039;&#039;ASC_Shading_Min_Elevation&#039;&#039;) und die Mindesttemperatur &#039;&#039;ASC_Shading_Min_OutsideTemperature&#039;&#039; - passt.&lt;br /&gt;
Dann sind die Winkelangaben festzulegen, ggf. kann ein Kompass zu Hilfe genommen werden (&#039;&#039;ASC_Shading_Direction&#039;&#039; ist die Richtung des Fensters, 90 Grad entspricht Ost, 180 Grad Süden, &#039;&#039;ASC_Shading_Angle_Left&#039;&#039; ist der Sonneneintritt ins Zimmer, wird von -Direction abgezogen, &#039;&#039;ASC_Shading_Angle_Right&#039;&#039; hat diesselbe Funktion für den Austrittswinkel.&lt;br /&gt;
&lt;br /&gt;
=== Weitere Funktionen ===&lt;br /&gt;
==== Privacy ====&lt;br /&gt;
Werden hierfür Werte festgelegt, werden die betreffenden Rollläden die festgelegte Zeit vor dem abendlichen Schließen vorab teilweise geschlossen. Dies kann z.B. gewünscht sein, um Rollläden zur Straße hin mit viel Fußgängerverkehr zwar nicht vollständig abzudunkeln, aber gleichzeitig zu verhindern, dass von außen in Wohnräume geschaut werden kann, sobald dort das Licht angeschaltet wird&lt;br /&gt;
==== BlockingTime====&lt;br /&gt;
Bewirkt, dass nach einer manuellen Fahrt wird eine vom ASC Modul initiierte Fahrt zunächst ausgesetzt wird, bis die im Attribute angegebene Zeit überschritten ist. Erst dann wird eine dann vom ASC Modul initiierte Fahrt tatsächlich durchgeführt.&lt;br /&gt;
Genau so wird ein hochfahren eines Rollos durch das ASC Modul nicht mehr ausgeführt wenn es innerhalb der Zeit von ASC_BlockingTime_beforNightClose und das runterfahren wird nicht mehr erfolgen wenn es innerhalb von ASC_BlockingTime_beforDayOpen ist.&lt;br /&gt;
Beispiel: Meine Tochter geht früh aus Haus und Ihre Rollos sind nicht hoch gefahren. Diese fahren auch nicht mehr hoch da die ausschließlich bei home (anwesend) fahren sollen. Nun kommt sie am Nachmittag um 16:23 Uhr nach Hause, eigentlich sollten nun die Rollos fahren. Doch die Sonnenuntergangsfahrt (schließen) wäre schon 16:51 Uhr und damit innerhalb der 3600 ASC_BlockingTime_beforNightClose. Die Rollos bleiben also unten. Es lohnt sich für die paar Minuten einfach nicht mehr.&lt;br /&gt;
==== wiggle====&lt;br /&gt;
Mit einem &amp;lt;code&amp;gt;set &amp;lt;ASC-Device&amp;gt; wiggle&amp;lt;/code&amp;gt; können alle Rollladen mit einem entsprechenden Attribut zu einer kurzen Fahrt veranlasst werden, nach Ablauf von einer Minute wieder um denselben Wert zurück. Dabei wird jeweils in die Richtung gefahren, die den weiteren Weg ermöglicht. Wenn also zu 70% geschlossen ist, wird der Rollladen hoch fahren.&lt;br /&gt;
==== Partymode ====&lt;br /&gt;
Dieser wird am ASC-Device selbst aktiviert mittels &amp;lt;code&amp;gt;set &amp;lt;ASC-Device&amp;gt; partyMode on&amp;lt;/code&amp;gt;. Alle Rollladen-Devices, welche das Attribut &#039;&#039;ASC_Partymode&#039;&#039; auf &#039;&#039;on&#039;&#039; gestellt haben, werden nicht mehr gesteuert. Der letzte Schaltbefehl, der durch ein Fensterevent oder Bewohnerstatus an die Rollläden gesendet wurde, beim Beenden des Modus durch &amp;lt;code&amp;gt;set ASC-Device partyMode off&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
==== lock-out ====&lt;br /&gt;
(tbd auch hier: Doku ist etwas verteilt, könnte man im Wiki jeweils unter einem eigenen Unterabschnitt im Zusammenhang darstellen)&lt;br /&gt;
&lt;br /&gt;
==== SelfDefense ====&lt;br /&gt;
Das bei einem absent nur da die Rollläden geschlossen werden wo das Fenster vergessen wurde zu schließen.&lt;br /&gt;
Beim wechsel in gone wird nur an den makierten Terassentüren (&#039;&#039;ASC_ShuttersPlace terrace&#039;&#039;) der Rollladen runter gefahren.&lt;br /&gt;
Weitere Attribute dazu: &#039;&#039;ASC_Self_Defense_Exclude&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sonstige Hinweise ==&lt;br /&gt;
* Werden Attribute geändert, kann es vereinzelt vorkommen, dass das ASC-Modul dies nicht mitbekommt und das tatsächliche Verhalten nicht den Erwartungen entspricht. In so einem Fall empfielt es sich, das NOTIFYDEV nochmals aufbauen zu lassen. Dazu werden zunächst mit &amp;lt;code&amp;gt;set &amp;lt;ASC-Modul&amp;gt; expert 1&amp;lt;/code&amp;gt; erweiterte Informationen bezüglich des NotifyDevs unter set und get aktiviert und anschließend ein &amp;lt;code&amp;gt;set &amp;lt;ASC-Modul&amp;gt; createNewNotifyDev&amp;lt;/code&amp;gt; ausgeführt.&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* {{Link2Forum|Topic=92628|LinkText=&amp;quot;Thread zum Modul im Forum&amp;quot;}}&lt;br /&gt;
* {{Link2Forum|Topic=90751|LinkText=&amp;quot;Thread zur Entwicklung im Forum&amp;quot;}} &lt;br /&gt;
* {{Link2Forum|Topic=73964|LinkText=&amp;quot;Thread zu den Scripten von user cluni&amp;quot;}}, die der Entwicklung des Moduls zugrunde liegen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;br /&gt;
[[Kategorie:Rollladensteuerung]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Wochenende,_Feiertage_und_Schulferien&amp;diff=30306</id>
		<title>Wochenende, Feiertage und Schulferien</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Wochenende,_Feiertage_und_Schulferien&amp;diff=30306"/>
		<updated>2019-05-01T09:01:18Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;FHEM bietet die Möglichkeit, Komponenten in Abhängigkeit von Wochenenden und Schulferien sowie Feiertagen zu steuern. Hier soll beschrieben werden, wie Schulferien einbezogen werden.&lt;br /&gt;
&lt;br /&gt;
== Wochenendermittlung mit $we ==&lt;br /&gt;
Um am Wochenende (Samstag und Sonntag) länger schlafen zu können, kann diese Steuerung durch Nutzung der Variable &#039;&#039;$we&#039;&#039; erweitert werden.&lt;br /&gt;
Diese hat am Wochenende den Wert &#039;&#039;1&#039;&#039;, an sonstigen Tagen den Wert &#039;&#039;0&#039;&#039;. In if-Abfragen wird die 0 als &#039;&#039;false/falsch&#039;&#039; interpretiert, andere numerische Werte als &#039;&#039;true/wahr&#039;&#039;. Man kann mittels &#039;&#039;if ($we)&#039;&#039; also ganz einfach prüfen, ob Wochenende ist und entsprechend steuern (oder auch nicht).&lt;br /&gt;
&lt;br /&gt;
Eine simple Rollladensteuerung um 7 Uhr morgens für jeden Tag sieht beispielsweise wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
 define RolloHoch at *07:00 set Rollo hoch&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel kann entsprechend ergänzt werden, so dass am Wochenende nicht um 7 Uhr das Rollo nach oben gefahren wird:&lt;br /&gt;
&lt;br /&gt;
  define RolloHoch at *07:00 { if (!($we)) { fhem(&amp;amp;quot;set Rollo hoch&amp;amp;quot;);; } }&lt;br /&gt;
&lt;br /&gt;
Das &#039;&#039;!&#039;&#039; in der if-Abfrage negiert den dahinter folgenden Ausdruck in der Klammer, ist also &amp;quot;nicht Wochenende&amp;quot;. Der Inhalt der äußeren geschweiften Klammern stellt echten Perl-Code dar (der hinter jeder Anweisung gerne ein Semikolon stehen hat, das in FHEM durch ein weiteres Semikolon [http://de.wikipedia.org/wiki/Maskierungszeichen maskiert/escaped] werden muss). Aus dem Perl-Code kann man mittels des Befehls &#039;&#039;fhem()&#039;&#039; wiederum FHEM-Code ausführen (hier der Befehl, um das Rollo nach oben zu fahren). Das (Doppel-)Semikolon ist in diesem Beispiel nicht zwingend notwendig, da es sich nur um eine einzige (und somit letzte) Anweisung handelt - man sollte sich jedoch aneignen, jede Anweisung im Perl-Code mit einem (Doppel-)Semikolon abzuschließen (eine schließende geschweifte Klammer stellt auch das Ende eine Anweisung bzw. eines Anweisungsblocks dar).&lt;br /&gt;
&lt;br /&gt;
== Feiertage mittels holiday-Datei ==&lt;br /&gt;
Samstags und Sonntags bleibt das Rollo nun unten und man kann länger schlafen. Um diesen Komfort auch an Feiertagen zu haben, können in FHEM mittels &#039;&#039;holiday&#039;&#039;-Dateien Feiertage definiert werden. Sinnvollerweise erstellt man sich für sein jeweiliges Bundesland eine eigene Datei, die Definitionen für feste Feiertage (z.B. Weihnachten oder der Tag der Deutschen Einheit) und solche in Abhängigkeit zu Ostern (z.B. Ostermontag oder Pfingsten, im Rheinland auch der Karneval) beinhaltet. Eine gutes Beispiel mit Erklärung findet sich in der [http://fhem.de/Heimautomatisierung-mit-fhem.pdf FHEM-Übersicht für Anfänger].&lt;br /&gt;
Nachdem beispielsweise die &#039;&#039;BW_Feiertag.holiday&#039;&#039;-Datei im FHEM-Ordner erstellt/abgelegt wurde, kann diese in die Konfiguration eingebunden werden. Mittels &#039;&#039;holiday2we&#039;&#039; können die darin definierten Feiertage mit der Variable &#039;&#039;$we&#039;&#039; &amp;quot;verheiratet&amp;quot; werden. &#039;&#039;if ($we)&#039;&#039; ist danach immer wahr, sobald Wochenende oder ein Feiertag ist:&lt;br /&gt;
&lt;br /&gt;
  attr global holiday2we BW_Feiertag&lt;br /&gt;
  define BW_Feiertag holiday&lt;br /&gt;
&lt;br /&gt;
=== Mitgelieferte holiday-Dateien ===&lt;br /&gt;
FHEM liefert eine Reihe von vordefinierten holiday-Dateien mit:&lt;br /&gt;
&lt;br /&gt;
* Dateien für die deutschen Bundesländer (abgekürzt laut [https://www.bmel-statistik.de/footernavigation/archiv/statistischer-monatsbericht/abkuerzungen-der-bundeslaender/ amtlicher Liste]), z.B. &#039;&#039;hh.holiday&#039;&#039; für Hamburg.&lt;br /&gt;
* Feiertage in Österreich: &#039;&#039;aut.holiday&#039;&#039;&lt;br /&gt;
* Feiertage im Vereinigten Königreich und Nordirland: &#039;&#039;en.holiday&#039;&#039;&lt;br /&gt;
* Islamische Feiertage: &#039;&#039;islam20xx.holiday&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Feiertage mittels Internet-Kalender ==&lt;br /&gt;
{{Randnotiz|RNText=Alle x Stunden -wie hier dargestellt- einen unveränderten Jahres-Ferienkalender aus dem Internet erneut abzurufen ist nicht sinnvoll, da unnötige Abhängigkeiten des FHEM-Servers zur Verfügbarkeit des externen Servers entstehen. Zudem erzeugt dies unnötige Last auf dem externen Server. Besser ist es, nur einmal jährlich den Ferienkalender abzurufen und auf dem eigenen FHEM-Server zu speichern. Das Vorgehen ist beispielhaft in {{Link2Forum|Topic=36244|Message=299631}} beschrieben.}}&lt;br /&gt;
Theoretisch kann man in o.a. Datei auch seine persönlichen Urlaube oder die Schulferien definieren. Hier eignet sich jedoch die &#039;&#039;Calendar&#039;&#039;-Funktion wesentlich besser. V.a. die Schulferien der einzelnen Bundesländer sind im Internet (z.B. unter [http://www.ferienwiki.de ferienwiki.de]) als iCal-Datei verfügbar und können wie folgt in FHEM eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
  define BW_Ferien Calendar ical url https://www.ferienwiki.de/exports/ferien/2017/de/baden-wuerttemberg 86400&lt;br /&gt;
&lt;br /&gt;
Das Intervall von 86400 Sekunden (entspricht 24 Stunden) für die Aktualisierung der Schulferien sollte im Normalbetrieb mehr als ausreichen. Wenn eigene Kalender (z.B. bei Google) für Urlaubstage genutzt werden, muss man individuell abwägen, wie oft dieser aktualisiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Um nun diesen Kalender nun nutzen zu können, benötigt FHEM einen &#039;&#039;dummy&#039;&#039;, der entsprechend abgefragt werden kann:&lt;br /&gt;
&lt;br /&gt;
  define BW_Ferientag dummy&lt;br /&gt;
  define BW_Ferien.notify notify BW_Ferien { \&lt;br /&gt;
         fhem &amp;amp;quot;set BW_Ferientag &amp;amp;quot; . (ReadingsVal(&amp;amp;quot;BW_Ferien&amp;amp;quot;, &amp;amp;quot;modeStart&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;) =~ &amp;amp;quot;ferien&amp;amp;quot;&amp;amp;#160;? 1: 0) }&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;BW_Ferientag&#039;&#039; ist in diesem Beispiel der angesprochene &#039;&#039;dummy&#039;&#039; und kann mittels &#039;&#039;Value(&amp;quot;BW_Ferientag&amp;quot;)&#039;&#039; abgefragt werden. Im &#039;&#039;notify&#039;&#039; wird der Wert gesetzt, sobald der Kalender aktualisiert wird: Eine &#039;&#039;1&#039;&#039; für einen Tag, an dem der Text &amp;quot;ferien&amp;quot; in einem Ereignis vorkommt, das sich im &#039;&#039;modeStart&#039;&#039;Modus (vgl. {{Link2CmdRef|Anker=Calendar}} - &#039;&#039;The start time has passed but the end time of the calendar event is not yet reached.&#039;&#039;) befindet, ansonsten &#039;&#039;0&#039;&#039;. Das Vorkommen des Textes ist in den Ereignissen der oben genutzten Quelle immer der Fall.&lt;br /&gt;
&lt;br /&gt;
Um ein Rollo nun weder am Wochenende, an Feiertagen, noch zu Schulferien morgens hochfahren zu lassen, lautet das Beispiel:&lt;br /&gt;
&lt;br /&gt;
  define RolloHoch at *07:00 { if (&amp;amp;#160;!($we) &amp;amp;amp;&amp;amp;amp;&amp;amp;#160;!(Value(&amp;amp;quot;BW_Ferientag&amp;amp;quot;)) ) { fhem(&amp;amp;quot;set Rollo hoch&amp;amp;quot;);; } }&lt;br /&gt;
&lt;br /&gt;
Ausgehend von diesem Artikel ist unter [[Google-Kalender zur Steuerung von Dummies]] eine Vorgehensweise zur&lt;br /&gt;
Steuerung von FHEM mit dem Google-Kalender veröffentlicht.&lt;br /&gt;
&lt;br /&gt;
Diese Methode unterstützt jedoch nicht die Feiertagserkennung des {{Link2CmdRef|Lang=de|Anker=DOIF|Label=DOIF}}-Moduls, speziell im Abschnitt {{Link2CmdRef|Lang=de|Anker=DOIF_Wochentagsteuerung|Label=Wochentagssteuerung}}. Hier wird nur der Status der &#039;&#039;$we&#039;&#039;-Variable abgefragt und die Methode mit dem eigenen Holiday-Kalender empfohlen.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]] [[Kategorie:HOWTOS]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Wochenende,_Feiertage_und_Schulferien&amp;diff=30304</id>
		<title>Wochenende, Feiertage und Schulferien</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Wochenende,_Feiertage_und_Schulferien&amp;diff=30304"/>
		<updated>2019-04-30T20:59:26Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Hinweis auf mitgelieferte holiday-Dateien&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;FHEM bietet die Möglichkeit, Komponenten in Abhängigkeit von Wochenenden und Schulferien sowie Feiertagen zu steuern. Hier soll beschrieben werden, wie Schulferien einbezogen werden.&lt;br /&gt;
&lt;br /&gt;
== Wochenendermittlung mit $we ==&lt;br /&gt;
Um am Wochenende (Samstag und Sonntag) länger schlafen zu können, kann diese Steuerung durch Nutzung der Variable &#039;&#039;$we&#039;&#039; erweitert werden.&lt;br /&gt;
Diese hat am Wochenende den Wert &#039;&#039;1&#039;&#039;, an sonstigen Tagen den Wert &#039;&#039;0&#039;&#039;. In if-Abfragen wird die 0 als &#039;&#039;false/falsch&#039;&#039; interpretiert, andere numerische Werte als &#039;&#039;true/wahr&#039;&#039;. Man kann mittels &#039;&#039;if ($we)&#039;&#039; also ganz einfach prüfen, ob Wochenende ist und entsprechend steuern (oder auch nicht).&lt;br /&gt;
&lt;br /&gt;
Eine simple Rollladensteuerung um 7 Uhr morgens für jeden Tag sieht beispielsweise wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
 define RolloHoch at *07:00 set Rollo hoch&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel kann entsprechend ergänzt werden, so dass am Wochenende nicht um 7 Uhr das Rollo nach oben gefahren wird:&lt;br /&gt;
&lt;br /&gt;
  define RolloHoch at *07:00 { if (!($we)) { fhem(&amp;amp;quot;set Rollo hoch&amp;amp;quot;);; } }&lt;br /&gt;
&lt;br /&gt;
Das &#039;&#039;!&#039;&#039; in der if-Abfrage negiert den dahinter folgenden Ausdruck in der Klammer, ist also &amp;quot;nicht Wochenende&amp;quot;. Der Inhalt der äußeren geschweiften Klammern stellt echten Perl-Code dar (der hinter jeder Anweisung gerne ein Semikolon stehen hat, das in FHEM durch ein weiteres Semikolon [http://de.wikipedia.org/wiki/Maskierungszeichen maskiert/escaped] werden muss). Aus dem Perl-Code kann man mittels des Befehls &#039;&#039;fhem()&#039;&#039; wiederum FHEM-Code ausführen (hier der Befehl, um das Rollo nach oben zu fahren). Das (Doppel-)Semikolon ist in diesem Beispiel nicht zwingend notwendig, da es sich nur um eine einzige (und somit letzte) Anweisung handelt - man sollte sich jedoch aneignen, jede Anweisung im Perl-Code mit einem (Doppel-)Semikolon abzuschließen (eine schließende geschweifte Klammer stellt auch das Ende eine Anweisung bzw. eines Anweisungsblocks dar).&lt;br /&gt;
&lt;br /&gt;
== Feiertage mittels holiday-Datei ==&lt;br /&gt;
Samstags und Sonntags bleibt das Rollo nun unten und man kann länger schlafen. Um diesen Komfort auch an Feiertagen zu haben, können in FHEM mittels &#039;&#039;holiday&#039;&#039;-Dateien Feiertage definiert werden. Sinnvollerweise erstellt man sich für sein jeweiliges Bundesland eine eigene Datei, die Definitionen für feste Feiertage (z.B. Weihnachten oder der Tag der Deutschen Einheit) und solche in Abhängigkeit zu Ostern (z.B. Ostermontag oder Pfingsten, im Rheinland auch der Karneval) beinhaltet. Eine gutes Beispiel mit Erklärung findet sich in der [http://fhem.de/Heimautomatisierung-mit-fhem.pdf FHEM-Übersicht für Anfänger].&lt;br /&gt;
Nachdem beispielsweise die &#039;&#039;BW_Feiertag.holiday&#039;&#039;-Datei im FHEM-Ordner erstellt/abgelegt wurde, kann diese in die Konfiguration eingebunden werden. Mittels &#039;&#039;holiday2we&#039;&#039; können die darin definierten Feiertage mit der Variable &#039;&#039;$we&#039;&#039; &amp;quot;verheiratet&amp;quot; werden. &#039;&#039;if ($we)&#039;&#039; ist danach immer wahr, sobald Wochenende oder ein Feiertag ist:&lt;br /&gt;
&lt;br /&gt;
  attr global holiday2we BW_Feiertag&lt;br /&gt;
  define BW_Feiertag holiday&lt;br /&gt;
&lt;br /&gt;
=== Mitgelieferte holiday-Dateien ===&lt;br /&gt;
FHEM liefert eine Reihe von vordefinierten holiday-Dateien mit:&lt;br /&gt;
&lt;br /&gt;
* Dateien für die deutschen Bundesländer (abgekürzt laut [https://www.bmel-statistik.de/footernavigation/archiv/statistischer-monatsbericht/abkuerzungen-der-bundeslaender/ amtlicher Liste]), z.B. &#039;&#039;hh.holiday&#039;&#039; für Hamburg.&lt;br /&gt;
* Feiertage in Österreich: &#039;&#039;aut.holiday&#039;&#039;&lt;br /&gt;
* Feiertage im Vereinigten Königreich und Nordirland: &#039;&#039;en.holiday&#039;&#039;&lt;br /&gt;
* Islamische Feiertage: &#039;&#039;islam20xx.holiday&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Feiertage mittels Internet-Kalender ==&lt;br /&gt;
{{Randnotiz|RNText=Alle x Stunden -wie hier dargestellt- einen unveränderten Jahres-Ferienkalender aus dem Internet erneut abzurufen ist nicht sinnvoll, da unnötige Abhängigkeiten des FHEM-Servers zur Verfügbarkeit des externen Servers entstehen. Zudem erzeugt dies unnötige Last auf dem externen Server. Besser ist es, nur einmal jährlich den Ferienkalender abzurufen und auf dem eigenen FHEM-Server zu speichern. Das Vorgehen ist beispielhaft in {{Link2Forum|Topic=36244|Message=299631}} beschrieben.}}&lt;br /&gt;
Theoretisch kann man in o.a. Datei auch seine persönlichen Urlaube oder die Schulferien definieren. Hier eignet sich jedoch die &#039;&#039;Calendar&#039;&#039;-Funktion wesentlich besser. V.a. die Schulferien der einzelnen Bundesländer sind im Internet (z.B. unter [http://www.ferienwiki.de ferienwiki.de]) als iCal-Datei verfügbar und können wie folgt in FHEM eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
  define BW_Ferien Calendar ical url https://www.ferienwiki.de/exports/ferien/2017/de/baden-wuerttemberg 86400&lt;br /&gt;
&lt;br /&gt;
Das Intervall von 86400 Sekunden (entspricht 24 Stunden) für die Aktualisierung der Schulferien sollte im Normalbetrieb mehr als ausreichen. Wenn eigene Kalender (z.B. bei Google) für Urlaubstage genutzt werden, muss man individuell abwägen, wie oft dieser aktualisiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Um nun diesen Kalender nun nutzen zu können, benötigt FHEM einen &#039;&#039;dummy&#039;&#039;, der entsprechend abgefragt werden kann:&lt;br /&gt;
&lt;br /&gt;
  define BW_Ferientag dummy&lt;br /&gt;
  define BW_Ferien.notify notify BW_Ferien { \&lt;br /&gt;
         fhem &amp;amp;quot;set BW_Ferientag &amp;amp;quot; . (ReadingsVal(&amp;amp;quot;BW_Ferien&amp;amp;quot;, &amp;amp;quot;modeStart&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;) =~ &amp;amp;quot;ferien&amp;amp;quot;&amp;amp;#160;? 1: 0) }&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;BW_Ferientag&#039;&#039; ist in diesem Beispiel der angesprochene &#039;&#039;dummy&#039;&#039; und kann mittels &#039;&#039;Value(&amp;quot;BW_Ferientag&amp;quot;)&#039;&#039; abgefragt werden. Im &#039;&#039;notify&#039;&#039; wird der Wert gesetzt, sobald der Kalender aktualisiert wird: Eine &#039;&#039;1&#039;&#039; für einen Tag, an dem der Text &amp;quot;ferien&amp;quot; in einem Ereignis vorkommt, das sich im &#039;&#039;modeStart&#039;&#039;Modus (vgl. {{Link2CmdRef|Anker=Calendar}} - &#039;&#039;The start time has passed but the end time of the calendar event is not yet reached.&#039;&#039;) befindet, ansonsten &#039;&#039;0&#039;&#039;. Das Vorkommen des Textes ist in den Ereignissen der oben genutzten Quelle immer der Fall.&lt;br /&gt;
&lt;br /&gt;
Um ein Rollo nun weder am Wochenende, an Feiertagen, noch zu Schulferien morgens hochfahren zu lassen, lautet das Beispiel:&lt;br /&gt;
&lt;br /&gt;
  define RolloHoch at *07:00 { if (&amp;amp;#160;!($we) &amp;amp;amp;&amp;amp;amp;&amp;amp;#160;!(Value(&amp;amp;quot;BW_Ferientag&amp;amp;quot;)) ) { fhem(&amp;amp;quot;set Rollo hoch&amp;amp;quot;);; } }&lt;br /&gt;
&lt;br /&gt;
Ausgehend von diesem Artikel ist unter [[Google-Kalender zur Steuerung von Dummies]] eine Vorgehensweise zur&lt;br /&gt;
Steuerung von FHEM mit dem Google-Kalender veröffentlicht.&lt;br /&gt;
&lt;br /&gt;
Diese Methode unterstützt jedoch nicht die Feiertagserkennung des {{Link2CmdRef|Lang=de|Anker=DOIF|Label=DOIF}}-Moduls, speziell im Abschnitt {{Link2CmdRef|Lang=de|Anker=DOIF_Wochentagsteuerung|Label=Wochentagssteuerung}}. Hier wird nur der Status der &#039;&#039;$we&#039;&#039;-Variable abgefragt und die Methode mit dem eigenen Holiday-Kalender empfohlen.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Holiday&amp;diff=30303</id>
		<title>Holiday</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Holiday&amp;diff=30303"/>
		<updated>2019-04-30T20:51:03Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Weiterleitungsziel von &amp;quot;Wochenende, Feiertage und Schulferien&amp;quot; nach Wochenende, Feiertage und Schulferien geändert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Wochenende, Feiertage und Schulferien]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Holiday&amp;diff=30302</id>
		<title>Holiday</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Holiday&amp;diff=30302"/>
		<updated>2019-04-30T20:50:34Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Added redirect for holiday&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[&amp;quot;Wochenende, Feiertage und Schulferien&amp;quot;]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=FAQ&amp;diff=29144</id>
		<title>FAQ</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=FAQ&amp;diff=29144"/>
		<updated>2019-01-17T11:24:22Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Zweck ==&lt;br /&gt;
Auf dieser Seite möchte ich Einträge zu FAQ (frequently asked questions, häufige Fragen) sammeln.&lt;br /&gt;
&lt;br /&gt;
== Fragen? Antworten! ==&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;Ich möchte ein Gerät x mal alle y Minuten starten, aber nur von xx:xx bis yy:yy.&amp;lt;/dt&amp;gt;&lt;br /&gt;
&amp;lt;dd&amp;gt;Du möchtest eine [[Zeitschaltuhr]].&amp;lt;dd&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--  &lt;br /&gt;
Template neue Frage/Antwort&lt;br /&gt;
&amp;lt;dt&amp;gt;Frage&amp;lt;/dt&amp;gt;&lt;br /&gt;
&amp;lt;dd&amp;gt;Antwort&amp;lt;/dd&amp;gt;&lt;br /&gt;
--&amp;gt; &lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=FAQ&amp;diff=29143</id>
		<title>FAQ</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=FAQ&amp;diff=29143"/>
		<updated>2019-01-17T11:23:48Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Zweck ==&lt;br /&gt;
Auf dieser Seite möchte ich Einträge zu FAQ (frequently asked questions, häufige Fragen) sammeln.&lt;br /&gt;
&lt;br /&gt;
== Fragen? Antworten! ==&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;Ich möchte ein Gerät x mal alle y Minuten starten, aber nur von xx:xx bis yy:yy.&amp;lt;/dt&amp;gt;&lt;br /&gt;
&amp;lt;dd&amp;gt;Siehe →[[Zeitschaltuhr]]&amp;lt;dd&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--  &lt;br /&gt;
Template neue Frage/Antwort&lt;br /&gt;
&amp;lt;dt&amp;gt;Frage&amp;lt;/dt&amp;gt;&lt;br /&gt;
&amp;lt;dd&amp;gt;Antwort&amp;lt;/dd&amp;gt;&lt;br /&gt;
--&amp;gt; &lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Benutzer_Diskussion:ChristophMorrison&amp;diff=29142</id>
		<title>Benutzer Diskussion:ChristophMorrison</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Benutzer_Diskussion:ChristophMorrison&amp;diff=29142"/>
		<updated>2019-01-17T11:23:22Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* Willkommen! */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hilf mit und erweitere die [[FAQ]]!&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=FAQ&amp;diff=29141</id>
		<title>FAQ</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=FAQ&amp;diff=29141"/>
		<updated>2019-01-17T11:22:51Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Erste FAQ hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Zweck ==&lt;br /&gt;
Auf dieser Seite möchte ich Einträge zu FAQ (frequently asked questions, häufige Fragen) sammeln.&lt;br /&gt;
&lt;br /&gt;
== Fragen? Antworten! ==&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;Ich möchte ein Gerät x mal alle y Minuten starten, aber nur von xx:xx bis yy:yy.&amp;lt;/dt&amp;gt;&lt;br /&gt;
&amp;lt;dd&amp;gt;Siehe →[[Zeitschaltuhr]]&amp;lt;dd&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--  &lt;br /&gt;
Template neue Frage/Antwort&lt;br /&gt;
&amp;lt;dt&amp;gt;Frage&amp;lt;/dt&amp;gt;&lt;br /&gt;
&amp;lt;dd&amp;gt;Antwort&amp;lt;/dd&amp;gt;&lt;br /&gt;
--&amp;gt; &lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Zeitschaltuhr&amp;diff=29140</id>
		<title>Zeitschaltuhr</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Zeitschaltuhr&amp;diff=29140"/>
		<updated>2019-01-17T09:53:04Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Anforderung ==&lt;br /&gt;
Eine Umwälzpumpe, die an einem FS20 Schalter hängt, soll zu bestimmten Tageszeiten alle 15 Minuten für jeweils 5 Minuten eingeschaltet werden - mit unterschiedlichen Zeiträumen je Wochentag.&lt;br /&gt;
&lt;br /&gt;
== Lösungsansatz 1: at ==&lt;br /&gt;
Es wird der [http://fhem.de/commandref.html#at at-Befehl] verwendet.&lt;br /&gt;
&lt;br /&gt;
Täglich zur gewünschten Startzeit wird geprüft, ob die Voraussetzungen erfüllt sind. Ist dies der Fall, wird die Pumpe n mal alle 15 Minuten für 5 Minuten eingeschaltet.&lt;br /&gt;
Die jeweilige Laufzeit der Pumpe wird durch on-for-timer in Sekunden angegeben (300 Sekunden).&lt;br /&gt;
&lt;br /&gt;
* Täglich 17 Uhr bis 23 Uhr (6 Stunden = 24 Wiederholungen à 15 Minuten)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define PumpeAbendsStart at *17:00:00 {&lt;br /&gt;
 { fhem(&amp;quot;define PumpeAbends at +*{24}00:15:00 set Umwaelzpumpe on-for-timer 300&amp;quot;) }&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* An Wochentagen 7 Uhr bis 9 Uhr (8 Wiederholungen), an Wochenenden 7 Uhr bis 17 Uhr (36 Wiederholungen)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define PumpeMorgensStart at *07:00:00 {&lt;br /&gt;
 if (!$we) {&lt;br /&gt;
   { fhem(&amp;quot;define PumpeMorgens at +*{8}00:15:00 set Umwaelzpumpe on-for-timer 300&amp;quot;) }&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   { fhem(&amp;quot;define PumpeMorgens at +*{36}00:15:00 set Umwaelzpumpe on-for-timer 300&amp;quot;) }&lt;br /&gt;
 }&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Lösungsansatz 2: at mit Prüflauf ==&lt;br /&gt;
Es wird ein dauerhafter Prüflauf genutzt, der alle 15 Minuten prüft, ob der Zeitpunkt der Ausführung erreicht ist.&lt;br /&gt;
&lt;br /&gt;
* An Wochentagen 7 Uhr bis 9 Uhr&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define pumpe_wd78 at +*00:15 { fhem(&amp;quot;set Umwaelzpumpe on-for-timer 300&amp;quot;) if(!$we &amp;amp;amp;&amp;amp;amp; $hour&amp;amp;gt;=7 &amp;amp;amp;&amp;amp;amp; $hour&amp;amp;lt;9) }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lösungsansatz 3: RandomTimer ==&lt;br /&gt;
Als (einfache) Alternative kann auch das Hilfsmodul [[RandomTimer]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
== Lösungsansatz 4: WeekdayTimer ==&lt;br /&gt;
Alternativ kann das Hilfsmodul [[WeekdayTimer]] genutzt werden.&lt;br /&gt;
&lt;br /&gt;
== Lösungsansatz 5: DOIF ==&lt;br /&gt;
Siehe [https://fhem.de/commandref_DE.html#DOIF_Intervall-Timer DOIF Intervall-Timer]&lt;br /&gt;
&lt;br /&gt;
== Weitere Beispiele ==&lt;br /&gt;
* [[AT zu einem absoluten Datum_ausführen|AT-Beispiele]]&lt;br /&gt;
* [[Wakeuplight|Wakeup-Light]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Zeitschaltuhr&amp;diff=29139</id>
		<title>Zeitschaltuhr</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Zeitschaltuhr&amp;diff=29139"/>
		<updated>2019-01-17T09:52:16Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Added DOIF example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Anforderung ==&lt;br /&gt;
Eine Umwälzpumpe, die an einem FS20 Schalter hängt, soll zu bestimmten Tageszeiten alle 15 Minuten für jeweils 5 Minuten eingeschaltet werden - mit unterschiedlichen Zeiträumen je Wochentag.&lt;br /&gt;
&lt;br /&gt;
== Lösungsansatz 1 ==&lt;br /&gt;
Es wird der [http://fhem.de/commandref.html#at at-Befehl] verwendet.&lt;br /&gt;
&lt;br /&gt;
Täglich zur gewünschten Startzeit wird geprüft, ob die Voraussetzungen erfüllt sind. Ist dies der Fall, wird die Pumpe n mal alle 15 Minuten für 5 Minuten eingeschaltet.&lt;br /&gt;
Die jeweilige Laufzeit der Pumpe wird durch on-for-timer in Sekunden angegeben (300 Sekunden).&lt;br /&gt;
&lt;br /&gt;
* Täglich 17 Uhr bis 23 Uhr (6 Stunden = 24 Wiederholungen à 15 Minuten)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define PumpeAbendsStart at *17:00:00 {&lt;br /&gt;
 { fhem(&amp;quot;define PumpeAbends at +*{24}00:15:00 set Umwaelzpumpe on-for-timer 300&amp;quot;) }&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* An Wochentagen 7 Uhr bis 9 Uhr (8 Wiederholungen), an Wochenenden 7 Uhr bis 17 Uhr (36 Wiederholungen)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define PumpeMorgensStart at *07:00:00 {&lt;br /&gt;
 if (!$we) {&lt;br /&gt;
   { fhem(&amp;quot;define PumpeMorgens at +*{8}00:15:00 set Umwaelzpumpe on-for-timer 300&amp;quot;) }&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   { fhem(&amp;quot;define PumpeMorgens at +*{36}00:15:00 set Umwaelzpumpe on-for-timer 300&amp;quot;) }&lt;br /&gt;
 }&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Lösungsansatz 2 ==&lt;br /&gt;
Es wird ein dauerhafter Prüflauf genutzt, der alle 15 Minuten prüft, ob der Zeitpunkt der Ausführung erreicht ist.&lt;br /&gt;
&lt;br /&gt;
* An Wochentagen 7 Uhr bis 9 Uhr&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define pumpe_wd78 at +*00:15 { fhem(&amp;quot;set Umwaelzpumpe on-for-timer 300&amp;quot;) if(!$we &amp;amp;amp;&amp;amp;amp; $hour&amp;amp;gt;=7 &amp;amp;amp;&amp;amp;amp; $hour&amp;amp;lt;9) }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lösungsansatz 3 ==&lt;br /&gt;
Als (einfache) Alternative kann auch das Hilfsmodul [[RandomTimer]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
== Lösungsansatz 4 ==&lt;br /&gt;
Alternativ kann das Hilfsmodul [[WeekdayTimer]] genutzt werden.&lt;br /&gt;
&lt;br /&gt;
== Lösungsansatz 5: DOIF ==&lt;br /&gt;
Siehe [https://fhem.de/commandref_DE.html#DOIF_Intervall-Timer DOIF Intervall-Timer]&lt;br /&gt;
&lt;br /&gt;
== Weitere Beispiele ==&lt;br /&gt;
* [[AT zu einem absoluten Datum_ausführen|AT-Beispiele]]&lt;br /&gt;
* [[Wakeuplight|Wakeup-Light]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Twilight&amp;diff=29130</id>
		<title>Twilight</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Twilight&amp;diff=29130"/>
		<updated>2019-01-16T14:39:09Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Updated maintainer info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hinweis|&#039;&#039;&#039;End of Live der Yahoo Weather API&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Da die Yahoo Weather API zum 03.01.2019 abgeschaltet wurde, kann &#039;&#039;&#039;Twilight&#039;&#039;&#039; aktuell keine Wetterdaten beziehen!}}&lt;br /&gt;
&lt;br /&gt;
{{Infobox Modul&lt;br /&gt;
|ModPurpose=Virtuelles Gerät zur Berechnung der Dämmerungszustände für eine gegebene Position&lt;br /&gt;
|ModType=h&lt;br /&gt;
&amp;lt;!-- |ModCategory=?? --&amp;gt;&lt;br /&gt;
&amp;lt;!-- |ModCmdRef={{Link2Forum|Topic=19922|LinkText=siehe Forum}} --&amp;gt;&lt;br /&gt;
|ModTechName=59_Twilight.pm&lt;br /&gt;
|ModForumArea=Unterstützende Dienste/Wettermodule&lt;br /&gt;
|ModOwner=Christoph Morrison ({{Link2FU|17701|Forum}} / [[Benutzer_Diskussion:ChristophMorrison|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[Twilight]] ist ein Hilfsmodul, das für eine über Koordinaten spezifizierte Position diverse Dämmerungszustände, Zeiten und die Helligkeit berechnet und als Readings bereitstellt. Darüber hinaus werden auch, sofern spezifiziert, über die Yahoo Wetter-ID Wetterinformationen bereitgestellt bzw. in die Berechnungen mit einbezogen.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
Keine.&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
=== Define ===&lt;br /&gt;
:&amp;lt;code&amp;gt;define &amp;lt;name&amp;gt; Twilight &amp;lt;latitude&amp;gt; &amp;lt;longitude&amp;gt; [&amp;lt;indoor_horizon&amp;gt; [&amp;lt;Weather_Position&amp;gt;]]&amp;lt;/code&amp;gt;&lt;br /&gt;
Die Bedeutung der Parameter:&lt;br /&gt;
;latitude / longitude&lt;br /&gt;
:Geokoordinaten, für die die Werte berechnet werden sollen&lt;br /&gt;
;indoor_horizon&lt;br /&gt;
:Virtueller Horizont &lt;br /&gt;
;Weather_Position&lt;br /&gt;
:Yahoo Wetter-ID für den gewünschten Standort; der eingegebene Wert wird als &amp;quot;internal value&amp;quot; &#039;&#039;&#039;WEATHER&#039;&#039;&#039; gespeichert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Attribute ===&lt;br /&gt;
&lt;br /&gt;
=== Readings ===&lt;br /&gt;
Eine Auswahl der Readings, die das angelegte Twilight-Objekt enthält:&lt;br /&gt;
;sr*&lt;br /&gt;
:verschiedene Werte für den Sonnenaufgang (&amp;quot;&#039;&#039;&#039;s&#039;&#039;&#039;un&#039;&#039;&#039;r&#039;&#039;&#039;ise&amp;quot;): astronomisch, bürgerlich, nautisch, ...&lt;br /&gt;
;ss*&lt;br /&gt;
:verschiedene Werte für den Sonnenuntergang (&amp;quot;&#039;&#039;&#039;s&#039;&#039;&#039;un&#039;&#039;&#039;s&#039;&#039;&#039;et&amp;quot;): astronomisch, bürgerlich, nautisch, ...&lt;br /&gt;
;nextEvent&lt;br /&gt;
:Name des Ereignisses, das als nächstes eintreten wird (z.&amp;amp;nbsp;B. &amp;quot;ss_weather&amp;quot;)&lt;br /&gt;
;nextEventTime&lt;br /&gt;
:Zeitpunkt, zu dem das (unter &#039;&#039;nextEvent&#039;&#039; benannte) nächste Ereignis eintreten wird&lt;br /&gt;
;light&lt;br /&gt;
:ein errechneter Helligkeitswert mit den folgenden möglichen Werten (zwischen 0 und 6):&lt;br /&gt;
:;0&lt;br /&gt;
::Völlige Dunkelheit; relativer Sonnenstand zum Horizont: -18&amp;amp;deg;&lt;br /&gt;
:;1&lt;br /&gt;
::astronomische Dämmerung; relativer Sonnenstand zum Horizont: zwischen -12&amp;amp;deg; und -18&amp;amp;deg;&lt;br /&gt;
:;2&lt;br /&gt;
::nautische Dämmerung; relativer Sonnenstand zum Horizont: zwischen -6&amp;amp;deg; und -12&amp;amp;deg;&lt;br /&gt;
:;3&lt;br /&gt;
::bürgerliche Dämmerung; relativer Sonnenstand zum Horizont: zwischen 0&amp;amp;deg; und -6&amp;amp;deg;&lt;br /&gt;
:;4&lt;br /&gt;
::&amp;quot;indoor&amp;quot;-Dämmerung; Sonnenstand zwischen &#039;&#039;&#039;indoor_horizon&#039;&#039;&#039; (sofern der Wert ungleich Null ist) und 0&amp;amp;deg;&lt;br /&gt;
:;5&lt;br /&gt;
::&amp;quot;Wetter&amp;quot;-Dämmerung; Sonnenstand zwischen &#039;&#039;&#039;indoor_horizon&#039;&#039;&#039; und einem virtuellen Wetter-Horizont (abhängig von der Angabe einer &#039;&#039;&#039;Weather_position&#039;&#039;&#039;)&lt;br /&gt;
:;6&lt;br /&gt;
::&amp;quot;normales&amp;quot; Tageslicht&lt;br /&gt;
;azimuth&lt;br /&gt;
:Azimut; Horizontalwinkel des Sonnenstands (0&amp;amp;deg;=Norden, 180&amp;amp;deg;=Süden, usw.)&lt;br /&gt;
;elevation&lt;br /&gt;
:Höhe des Sonnenstands&lt;br /&gt;
;twilight&lt;br /&gt;
:Dämmerungswert, errechnet aus der Höhe des Sonnenstands. Der Wert geht von 0% bis 100% bei einem Sonnenstand zwischen -12&amp;amp;deg; und 6&amp;amp;deg; (also während der Dämmerungsphase).&lt;br /&gt;
&lt;br /&gt;
=== Funktionen ===&lt;br /&gt;
:&amp;lt;code&amp;gt;twilight($twilight, $reading, $min, $max)&amp;lt;/code&amp;gt;&lt;br /&gt;
Funktion im Modul, um bei der Dämmerungsberechnung Minimal-/Maximalwerte (&amp;quot;frühestens/spätestens&amp;quot;) spezifizieren und das Ergebnis beispielsweise in einem &amp;lt;code&amp;gt;at&amp;lt;/code&amp;gt; weiterverarbeiten zu können.&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiel(e) ==&lt;br /&gt;
=== Kurzes Beispiel ===&lt;br /&gt;
Anwendung der Funktion &#039;&#039;twilight&#039;&#039; zur Zeitsteuerung:&lt;br /&gt;
:&amp;lt;code&amp;gt;define morgens at *{twilight(&amp;quot;myTL&amp;quot;,&amp;quot;sr_indoor&amp;quot;,&amp;quot;7:30&amp;quot;,&amp;quot;9:00&amp;quot;)} set Rollo on&amp;lt;/code&amp;gt;&lt;br /&gt;
Dieses &#039;&#039;&#039;at&#039;&#039;&#039; wird morgens zum Zeitpunkt &#039;&#039;sr_indoor&#039;&#039; des Twilight Objekts &#039;&#039;myTL&#039;&#039; - aber frühestens um 7:30 und spätestens um 9:00 Uhr - dem Gerät &#039;&#039;Rollo&#039;&#039; einen &#039;&#039;on&#039;&#039;-Befehl schicken. Das Objekt &#039;&#039;myTL&#039;&#039; muss natürlich vorher mit (beispielsweise) &lt;br /&gt;
:&amp;lt;code&amp;gt;define myTL Twilight 44.444444 8.888888 ...&amp;lt;/code&amp;gt;&lt;br /&gt;
definiert worden sein.&lt;br /&gt;
&lt;br /&gt;
=== Ausführliches Beispiel ===&lt;br /&gt;
[[Twilight Anwendungsbeispiel]] mit detaillierten Erläuterungen&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Weather&amp;diff=28943</id>
		<title>Weather</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Weather&amp;diff=28943"/>
		<updated>2019-01-04T16:37:30Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hinweis|&#039;&#039;&#039;End of Live der Yahoo Weather API&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Da die Yahoo Weather API zum 03.01.2019 abgeschaltet wurde, kann &#039;&#039;&#039;Weather&#039;&#039;&#039; keine Wetterdaten von Yahoo mehr beziehen!}}&lt;br /&gt;
&lt;br /&gt;
{{SEITENTITEL:Weather}}&lt;br /&gt;
{{&lt;br /&gt;
Infobox Modul&lt;br /&gt;
|ModPurpose=Wettervorhersagen von Yahoo abfragen.&lt;br /&gt;
|ModType=d&lt;br /&gt;
&amp;lt;!-- |ModCategory= (noch?) nicht verwendet --&amp;gt;&lt;br /&gt;
|ModCmdRef=Weather&lt;br /&gt;
|ModForumArea=Unterstützende Dienste/Wettermodule&lt;br /&gt;
|ModTechName=59_Weather.pm&lt;br /&gt;
|ModOwner=Dr. Boris Neubert&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Mit dem Modul [[Weather]] können aktuelle Wetterdaten und Wettervorhersagen für einen bestimmten Ort von der Yahoo-Wetter-API regelmäßig abgefragt werden. &lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
=== Define ===&lt;br /&gt;
siehe {{Link2CmdRef|Lang=de|Anker=Weatherdefine}}.&lt;br /&gt;
&lt;br /&gt;
=== Attribute ===&lt;br /&gt;
siehe {{Link2CmdRef|Lang=de|Anker=Weatherattr}}.&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiele ==&lt;br /&gt;
=== Beispiel zur Modul-Einrichtung ===&lt;br /&gt;
Zuerst einmal besuchen wir die [http://weather.yahoo.com Yahoo Wetterseite] und öffnen den Wetterbericht für die jeweilige Stadt (z.B. [http://weather.yahoo.com/germany/berlin/berlin-638242 Berlin]). In der URL des Wetterberichtes findet sich dann die sogenannte WOEID (WHERE-ON-EARTH-ID). Sie identifiziert die Wetterinfos, die FHEM abfragen soll. Für Berlin ist dies die Nummer 638242.&lt;br /&gt;
&lt;br /&gt;
In der [[Konfiguration]] richten wir dann folgendes ein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# – Wetterdaten erfassen -&lt;br /&gt;
define MeinWetter Weather 638242 3600 de&lt;br /&gt;
attr MeinWetter room Wettervorhersage&lt;br /&gt;
&lt;br /&gt;
# - Logfile für alle Wetter Daten (monatsweise getrennt) —&lt;br /&gt;
define FileLog_MeinWetter FileLog ./log/meinwetter-%Y-%m.log MeinWetter&lt;br /&gt;
attr FileLog_MeinWetter logtype text&lt;br /&gt;
attr FileLog_MeinWetter room Wettervorhersage&lt;br /&gt;
&lt;br /&gt;
# — Wetter Icons in vertikaler Ansicht hinzufügen —&lt;br /&gt;
define weblink_meinwetter weblink htmlCode {WeatherAsHtml(&amp;quot;MeinWetter&amp;quot;,7)}&lt;br /&gt;
attr weblink_meinwetter room Wettervorhersage&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das hat zur Folge, dass FHEM nun die Wetterdaten für Berlin (638242) jede Stunde (3600) neu abholt. Zudem wird eine vertikale Ansicht der Wetterdaten der nächsten 7 Tage erstellt. Die Anzeige erfolgt im Raum &amp;quot;Wettervorhersage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Konfigurationsschwierigkeiten ===&lt;br /&gt;
&lt;br /&gt;
Da Yahoo momentan auf mehreren Browsern Darstellungs-Schwierigkeiten hat, ist es schwer bis unmöglich, nach bestimmten Städten zu suchen (Search Box ist nicht erreichbar).&lt;br /&gt;
&lt;br /&gt;
Für diesen Fall gibt es aber noch die Möglichkeit, die WOEID auf [https://www.computerhilfen.de/hilfen-64-422419-0.html Yahoo WOEID: So bekommt man die &amp;quot;Where on Earth&amp;quot; ID einer Stadt!] zu erhalten.&lt;br /&gt;
Erfolgreich gefunden habe ich diese Seite übrigens über den Trick einer Internet-Suche nach &#039;&#039;mehreren&#039;&#039; dominant bekannten Städte-IDs (oder vielleicht einfach Internet-Suche nach &amp;quot;WOEID&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* Weblink mit Stadtangabe für Wetter-Icons-Anzeige definieren: {{Link2Forum|Topic=31428|Message=267555}}&lt;br /&gt;
* Einrichtung einer automatische Aktualisierung der Wetter-Anzeige-Seite (Weblinks): {{Link2Forum|Topic=34581|Message=268957}}&lt;br /&gt;
* Anzahl der Icons definieren: {{Link2Forum|Topic=20481|Message=253464}}&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Twilight_Anwendungsbeispiel&amp;diff=28941</id>
		<title>Twilight Anwendungsbeispiel</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Twilight_Anwendungsbeispiel&amp;diff=28941"/>
		<updated>2019-01-04T11:50:56Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Hinweis auf EoL der Yahoo Weather API&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hinweis|&#039;&#039;&#039;End of Live der Yahoo Weather API&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Da die Yahoo Weather API zum 03.01.2019 abgeschaltet wurde, kann &#039;&#039;&#039;Twilight&#039;&#039;&#039; aktuell keine Wetterdaten beziehen!}}&lt;br /&gt;
&lt;br /&gt;
Das Modul [[Twilight]] errechnet verschiedene Dämmerungsphasen und kalkuliert daraus einen wetter- und dämmerungsabhängigen Lichtwert, der den Grad der Außenhelligkeit angibt. Hier soll an einem Beispiel der Einsatz dieses Moduls zur Steuerung eines Ambient-Lichtes und einer Vitrinenbeleuchtung gezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Ziel: eine indirekte Beleuchtung, z. B. im Wohnzimmer, soll, sobald es zu dämmern anfängt bzw. wetterabhängig schon früh &amp;quot;gefühlt&amp;quot; dunkler wird, eingeschaltet werden. In diesem Beispiel wird eine dimmbare indirekte Beleuchtung (ein LED-Lichtschlauch) verwendet. Die Helligkeit des Lichtschlauchs soll bei nur leichter Dämmerung maximal sein und soll sich dann bei Dunkelheit bis auf 20% reduzieren. Die Vitrinenbeleuchtung (ebenfalls LED) soll ebenfalls nur dann eingeschaltet sein, wenn es nicht taghell ist, da man die da sowieso nicht sieht. Nachts soll die Beleuchtung natürlich nicht an sein, dazu wird hier auf eine Variable &amp;quot;Anwesend&amp;quot; zurückgegriffen, die beim Autor als Indikator für Nacht und Abwesenheitsbetrieb verwendet wird. Dies kann individuell angepasst werden. Anwesend=2 bedeutet &amp;quot;Die Bewohner sind im Bett&amp;quot; und Anwesend=4 bedeutet &amp;quot;Die Bewohner sind abwesend&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Neben der automatischen Beleuchtung soll auch ein manuelles Eingreifen möglich sein. So kann über einen Wandtaster sowohl das AmbientLight als auch die Vitrinenbeleuchtung ein- oder ausgeschaltet werden, wobei die Automatik nach einer bestimmten Zeit automatisch wieder greifen soll. Hier werden ein Homematic-Schaltaktor und ein Homematic-Dimmer verwendet, das Beispiel lässt sich leicht auf andere Komponenten übertragen.&lt;br /&gt;
&lt;br /&gt;
Zur Realisierung wurden einige Perl-Schnipsel in ein externes Modul ausgelagert, weil dies wesentlich übersichtlicher ist als die Inline-Definition in der fhem.cfg. Als Basis kann das Modul 99_Utils.pm genommen werden. Der Autor hat diese Datei kopiert, das Modul umbenannt, und den zusätzlichen Code eingetragen.&lt;br /&gt;
&lt;br /&gt;
== Definition des Twilight-Devices ==&lt;br /&gt;
Um überhaupt die Lichtwerte zur Verfügung zu haben, muss zunächst ein Twilight-Device erzeugt werden. Hierzu wird folgender Aufruf verwendet:&lt;br /&gt;
&lt;br /&gt;
Syntax: &amp;lt;code&amp;gt;define &amp;lt;name&amp;gt; Twilight &amp;lt;Längengrad&amp;gt; &amp;lt;Breitengrad&amp;gt; &amp;lt;Indoor_Horizont&amp;gt; &amp;lt;Yahoo-Wetter-ID&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beispiel für Helgoland:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define T twilight 54.18258 7.885938 1 709403&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier beispielhaft eine Eingabe direkt per telnet in FHEM auf Port 7072&lt;br /&gt;
&lt;br /&gt;
=== Code ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define T twilight 54.18258 7.885938 1 709403&lt;br /&gt;
&lt;br /&gt;
list T&lt;br /&gt;
Internals:&lt;br /&gt;
   CFGFN&lt;br /&gt;
   DEF        54.18258 7.885938 1 709403&lt;br /&gt;
   INDOOR_HORIZON 1&lt;br /&gt;
   LATITUDE   54.18258&lt;br /&gt;
   LONGITUDE  7.885938&lt;br /&gt;
   NAME       THelgo&lt;br /&gt;
   NR         751&lt;br /&gt;
   STATE      6&lt;br /&gt;
   TYPE       Twilight&lt;br /&gt;
   WEATHER    709403&lt;br /&gt;
   WEATHER_HORIZON 6&lt;br /&gt;
   Readings:&lt;br /&gt;
     2012-03-30 08:40:34   light           6&lt;br /&gt;
     2012-03-30 08:40:34   nextEvent       ss_weather&lt;br /&gt;
     2012-03-30 08:40:34   nextEventTime   19:13:23&lt;br /&gt;
     2012-03-30 08:40:34   nextUpdate      08:55:34&lt;br /&gt;
     2012-03-30 08:40:34   sr              07:10:41&lt;br /&gt;
     2012-03-30 08:40:34   sr_astro        04:57:56&lt;br /&gt;
     2012-03-30 08:40:34   sr_civil        06:28:52&lt;br /&gt;
     2012-03-30 08:40:34   sr_indoor       07:17:33&lt;br /&gt;
     2012-03-30 08:40:34   sr_naut         05:45:13&lt;br /&gt;
     2012-03-30 08:40:34   sr_weather      07:51:46&lt;br /&gt;
     2012-03-30 08:40:34   ss              19:54:28&lt;br /&gt;
     2012-03-30 08:40:34   ss_astro        22:07:13&lt;br /&gt;
     2012-03-30 08:40:34   ss_civil        20:36:17&lt;br /&gt;
     2012-03-30 08:40:34   ss_indoor       19:47:36&lt;br /&gt;
     2012-03-30 08:40:34   ss_naut         21:19:56&lt;br /&gt;
     2012-03-30 08:40:34   ss_weather      19:13:23&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zu sehen ist hier die Übersicht der entsprechenden Dämmerungszeiten des aktuellen Tages (Details siehe FHEM {{Link2CmdRef|Anker=Twilight}}).&lt;br /&gt;
&lt;br /&gt;
== Berechnung des Automatik-Wertes ==&lt;br /&gt;
&lt;br /&gt;
In folgender Routine wird zunächst abhängig vom Lichtwert und der aktuellen Anwesenheit der Automatikwert für den Lichtschlauch und die Schrankbeleuchtung errechnet. Der Lichtschlauch ist ein Dimmer, erhält also Werte zwischen 0% und 100% und die Vitrine ist ein Schaltaktor, ist also entweder an oder aus.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 sub calc_a_schlauch{&lt;br /&gt;
  my $licht=ReadingsVal(&amp;quot;T&amp;quot;,&amp;quot;light&amp;quot;,&amp;quot;6&amp;quot;);&lt;br /&gt;
  my $anwesend=ReadingsVal(&amp;quot;anwesend&amp;quot;,&amp;quot;state&amp;quot;,&amp;quot;4&amp;quot;);&lt;br /&gt;
  if($licht eq 6 || $anwesend eq 2 || $anwesend eq 4){&lt;br /&gt;
    fhem &amp;quot;set a_schlauch 0&amp;quot; ;&lt;br /&gt;
    fhem &amp;quot;set a_schrank off&amp;quot;;&lt;br /&gt;
  }elsif($licht&amp;lt;6 &amp;amp;&amp;amp; $licht&amp;gt;3){&lt;br /&gt;
    fhem &amp;quot;set a_schlauch 100&amp;quot;;&lt;br /&gt;
    fhem &amp;quot;set a_schrank on&amp;quot;;&lt;br /&gt;
  }elsif($licht&amp;gt;2 &amp;amp;&amp;amp; $licht&amp;lt;5){&lt;br /&gt;
    fhem &amp;quot;set a_schlauch 40&amp;quot;;&lt;br /&gt;
    fhem &amp;quot;set a_schrank on&amp;quot;;&lt;br /&gt;
  }elsif($licht&amp;lt;3){&lt;br /&gt;
    fhem &amp;quot;set a_schlauch 20&amp;quot;;&lt;br /&gt;
    fhem &amp;quot;set a_schrank on&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Ausgangsbedingungen &amp;quot;light&amp;quot; und &amp;quot;anwesend&amp;quot; werden zu Beginn abgefragt. In der darauffolgenden IF-Anweisung wird dann je nach Lichtstärke ein Wert für die beiden Automatikwerte gesetzt. Zu beachten ist, dass die Devices a_schlauch und a_schrank Dummy-Devices sind (siehe fhem.cfg unten). Hier wird noch nicht direkt geschaltet sondern nur ein Wert berechnet und zwischengespeichert.&lt;br /&gt;
&lt;br /&gt;
== Manuelle Schaltung Vitrine ==&lt;br /&gt;
&lt;br /&gt;
Zur manuellen Schaltung wird durch das Drücken eines Tasters folgender Schnipsel ausgeführt, der dann den neuen Manuell-Wert berechnet:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sub calc_m_schrank{&lt;br /&gt;
  my $aktuell = ReadingsVal(&amp;quot;m_schrank&amp;quot;,&amp;quot;state&amp;quot;,&amp;quot;auto&amp;quot;);&lt;br /&gt;
  my $auto = ReadingsVal(&amp;quot;a_schrank&amp;quot;,&amp;quot;state&amp;quot;,&amp;quot;off&amp;quot;);&lt;br /&gt;
  if($aktuell eq &amp;quot;off&amp;quot; || ($aktuell eq &amp;quot;auto&amp;quot;) &amp;amp;&amp;amp; $auto eq &amp;quot;off&amp;quot;){&lt;br /&gt;
    fhem &amp;quot;set m_schrank on&amp;quot;;&lt;br /&gt;
  }else{&lt;br /&gt;
    fhem &amp;quot;set m_schrank off&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die aktuellen Werte für Manuell und Automatik werden zunächst aus den Dummy-Devices abgefragt. Jetzt gibt es zwei Möglichkeiten. Wenn die Vitrine gerade in dem Zustand ist, dass sie schon manuell ausgeschaltet wurde (also $aktuell eq &amp;quot;off&amp;quot;), dann muss sie jetzt eingeschaltet werden. Dies muss auch dann passieren, wenn man gerade im Automatikmodus ist, und eben dieser gerade auf &amp;quot;off&amp;quot; steht. Dies ist wichtig, damit für den Anwender, dem nicht klar ist, in welcher Betriebsart die Beleuchtung gerade ist, bei jedem Tasterdruck auch ein sichtbarer Schaltvorgang ausgelöst wird.&lt;br /&gt;
&lt;br /&gt;
== Manuelle Schaltung LED-Schlauch ==&lt;br /&gt;
&lt;br /&gt;
Die manuelle Schaltung des LED-Schlauchs ist noch etwas aufwendiger, da mehrere Dimmerstufen angefahren werden sollen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sub calc_m_schlauch{&lt;br /&gt;
  my $aktuell = ReadingsVal(&amp;quot;m_schlauch&amp;quot;,&amp;quot;state&amp;quot;,0);&lt;br /&gt;
  my $auto = ReadingsVal(&amp;quot;a_schlauch&amp;quot;,&amp;quot;state&amp;quot;,0);&lt;br /&gt;
  if($aktuell==0 || ($aktuell==-1 &amp;amp;&amp;amp; $auto==0)){&lt;br /&gt;
     fhem &amp;quot;set m_schlauch 100&amp;quot;;&lt;br /&gt;
  }elsif($aktuell==100){&lt;br /&gt;
     fhem &amp;quot;set m_schlauch 30&amp;quot;;&lt;br /&gt;
  }elsif($aktuell==30 || ($aktuell==-1 &amp;amp;&amp;amp; $auto&amp;gt;0)){&lt;br /&gt;
     fhem &amp;quot;set m_schlauch 0&amp;quot;;&lt;br /&gt;
  }else{&lt;br /&gt;
     fhem &amp;quot;set m_schlauch 0&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Prinzip ist wie bei der Vitrine. Da hier mit numerischen Werten gearbeitet wird, ist die Bedeutung &amp;quot;Automatik&amp;quot; nicht als &amp;quot;auto&amp;quot; definiert sondern als Zahlenwert &amp;quot;-1&amp;quot;. D.h. der Wert für &amp;quot;m_schlauch&amp;quot; kann zwischen -1 und 100 schwanken, wobei im Bereich 0-100 ein manueller Wert gesetzt wird und bei &amp;quot;-1&amp;quot; die Automatik greifen soll.&lt;br /&gt;
&lt;br /&gt;
In der IF-Abfrage wird zunächst der Fall behandelt, dass das Licht komplett aus ist. Dies ist entweder der Fall, wenn es manuell aus ist oder die Automatik greift und diese aber auch auf &amp;quot;0&amp;quot; ist. Der zweite Zweig schaltet den manuellen Wert auf 30 runter, wenn dieser gerade auf 100 ist. In allen anderen Fällen wird das Licht im nächsten Schritt manuell ausgeschaltet.&lt;br /&gt;
&lt;br /&gt;
== Schalten der Aktoren ==&lt;br /&gt;
&lt;br /&gt;
Letztlich müssen natürlich die Aktoren tatsächlich geschaltet werden. Dazu wird folgende &amp;quot;Treiber&amp;quot;-Routine genutzt, die die manuellen und automatischen Werte logisch kombiniert:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sub drive_schrank_schlauch{&lt;br /&gt;
  my $dimmer=dimvalue(ReadingsVal(&amp;quot;dim_schlauch&amp;quot;,&amp;quot;state&amp;quot;,0));&lt;br /&gt;
  my $man=ReadingsVal(&amp;quot;m_schlauch&amp;quot;,&amp;quot;state&amp;quot;,0);&lt;br /&gt;
  my $auto=ReadingsVal(&amp;quot;a_schlauch&amp;quot;,&amp;quot;state&amp;quot;,0);&lt;br /&gt;
  my $newvalue;&lt;br /&gt;
  my $zeit=60;&lt;br /&gt;
&lt;br /&gt;
  if($man==-1){&lt;br /&gt;
    $newvalue=$auto;&lt;br /&gt;
  }else{&lt;br /&gt;
    $newvalue=$man;&lt;br /&gt;
    $zeit=5;&lt;br /&gt;
  }&lt;br /&gt;
  if($dimmer ne $newvalue){&lt;br /&gt;
    fhem &amp;quot;set dim_schlauch &amp;quot;.$newvalue.&amp;quot; 84000 &amp;quot;.$zeit;&lt;br /&gt;
  }&lt;br /&gt;
  my $schrank=ReadingsVal(&amp;quot;akt_schrank&amp;quot;,&amp;quot;state&amp;quot;,&amp;quot;off&amp;quot;);&lt;br /&gt;
  $man=ReadingsVal(&amp;quot;m_schrank&amp;quot;,&amp;quot;state&amp;quot;,&amp;quot;auto&amp;quot;);&lt;br /&gt;
  $auto=ReadingsVal(&amp;quot;a_schrank&amp;quot;,&amp;quot;state&amp;quot;,&amp;quot;off&amp;quot;);&lt;br /&gt;
  if($man eq &amp;quot;auto&amp;quot;){&lt;br /&gt;
    $newvalue=$auto;&lt;br /&gt;
  }else{&lt;br /&gt;
    $newvalue=$man;&lt;br /&gt;
  }&lt;br /&gt;
  if($schrank ne $newvalue){&lt;br /&gt;
    fhem &amp;quot;set akt_schrank &amp;quot;.$newvalue;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier wird nun zuerst der LED-Schlauch und dann der Schrank behandelt. Zunächst wird sowohl der aktuelle Wert des tatsächlichen Aktors (hier: dim_schlauch) als auch die Manuell- und Automatik-Werte abgefragt. Die Variable $newvalue soll den neuen Schaltwert erhalten. Dies wird deswegen eingesetzt, um einen Schaltbefehl nur dann über Funk zu senden, wenn sich der Zustand geändert hat. Die Variable $zeit wird hier genutzt, um beim automatischen Schalten den Dimmer sehr langsam fahren zu lassen, so dass es zu keiner abrupten merklichen Helligkeitsänderung kommt. Dies geht nur mit Homematic-Dimmern.&lt;br /&gt;
&lt;br /&gt;
In der folgenden IF-Abfrage wird geklärt, ob der Dimmer im manuellen oder automatischen Modus betrieben wird. Dementsprechend wird $newvalue gesetzt. Bei manuellem Betrieb wird die Zeit auf 5 Sekunden runtergesetzt, denn hier soll eine merkliche Helligkeitsänderung in kurzer Zeit nach dem Betätigen des Tasters erfolgen. Stellt sich dann in der kommenden Abfrage heraus, dass der aktuelle Wert des Aktors noch nicht dem von $newvalue entspricht, wird ein tatsächlicher Schaltvorgang ausgelöst. Die Zahl 84000 ist die Einschaltzeit des Dimmers (unwichtig hier, muss nur hoch genug sein, ist aus Sicherheitsgründen nicht auf 0=unendlich - so geht der Dimmer auch bei einem FHEM-Ausfall nach knapp 24 Stunden aus).&lt;br /&gt;
Im weiteren Verlauf wird die Vitrine nach dem gleichen Prinzip geschaltet, wobei hier keine Zeit sinnvoll ist.&lt;br /&gt;
&lt;br /&gt;
=== fhem.cfg ===&lt;br /&gt;
In der fhem.cfg müssen, damit die Schnipsel funktionieren, neben dem Twilight-Device auch die Dummy-Devices, die beiden Aktoren, und entsprechende At-/Notify-Defines eingetragen werden, die dafür sorgen, dass die Code-Schnipsel ausgeführt werden. Die Definition der beiden Aktoren ist hier nicht aufgeführt und muss individuell eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define a_schlauch dummy&lt;br /&gt;
define m_schlauch dummy&lt;br /&gt;
define a_schrank dummy&lt;br /&gt;
define m_schrank dummy&lt;br /&gt;
define T twilight 54.18258 7.885938 1 709403&lt;br /&gt;
set m_schlauch -1&lt;br /&gt;
set m_schrank auto&lt;br /&gt;
&lt;br /&gt;
define m_a_schlauch notify m_a_schlauch {calc_a_schlauch();;}&lt;br /&gt;
define n_abwesend_ambient notify anwesend {fhem &amp;quot;trigger m_a_schlauch&amp;quot;;;}&lt;br /&gt;
define n_lightchange_ambient notify T:light.* {fhem &amp;quot;trigger m_a_schlauch&amp;quot;;;}&lt;br /&gt;
define n_d_schlauch notify a_schlauch {drive_schrank_schlauch();;}&lt;br /&gt;
define n_d_schlauch2 notify m_schlauch {drive_schrank_schlauch();;}&lt;br /&gt;
define n_d_schrank notify a_schrank {drive_schrank_schlauch();;}&lt;br /&gt;
define n_d_schrank2 notify m_schrank {drive_schrank_schlauch();;}&lt;br /&gt;
define n_m_schlauch_reset notify m_schlauch {fhem &amp;quot;delete temp_at_m_schlauch_reset&amp;quot;;;fhem &amp;quot;define temp_at_m_schlauch_reset at +01:00:00 set m_schlauch -1&amp;quot;;;}&lt;br /&gt;
define n_m_schrank_reset notify m_schrank {fhem &amp;quot;delete temp_at_m_schrank_reset&amp;quot;;;fhem &amp;quot;define temp_at_m_schrank_reset at +01:00:00 set m_schrank auto&amp;quot;;;}&lt;br /&gt;
define n_m_schlauch notify taster_wohn:Btn1.off[^L]* {calc_m_schlauch();;}&lt;br /&gt;
define n_m_schrank notify taster_wohn:Btn2.on[^L]* {calc_m_schrank();;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;m_a_schlauch&amp;lt;/code&amp;gt; ist ein Makro, was hier überflüssig erscheint, aber sinnvoll ist, wenn man einen Perl-Aufruf von verschiedenen Stellen aus antriggern will, so ist man unabängig vom tatsächlichen Inhalt.&lt;br /&gt;
&lt;br /&gt;
Die Berechnung wird also immer dann angetriggert, wenn entweder der Anwesenheitsstatus oder der Lichtwert sich verändert haben. Die folgenden Notifys reagieren auf Werteänderungen der Automatik- und Manuell-Dummys. Die nächsten beiden Notifys (&amp;lt;code&amp;gt;n_m_schlauch_reset&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;n_m_schrank_reset&amp;lt;/code&amp;gt;) sorgen dafür, dass bei einer Änderung der Manuell-Werte durch das Drücken von Tastern, etc. der Wert nach einer Stunde wieder auf Automatik zurückfällt. Die letzten beiden Notifys reagieren auf genau diese Taster, wobei hier ein Homematic-Wandtaster eingesetzt wird, bei dem nur auf einen kurzen Tastendruck reagiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Der bisherige Code sieht nicht vor, mit den Tastern auch frühzeitig wieder auf Automatik zurückzuschalten. Das kann z. B. mit einem zusätzlichen Taster gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define n_tEingang_lichtReset notify taster_eingang:Btn1.offLong.* {lichtReset();;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier wird auf den langen Tastendruck eines anderen Tasters reagiert, wobei dieser Notify zündet, sobald man den Taster länger als 0,4 Sekunden festhält, also noch bevor dieser losgelassen wird. Der Code von lichtReset kann dann mehr tun, als nur die beiden hier beschriebenen Beleuchtungen auf Automatik zu setzen. Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sub lichtReset{&lt;br /&gt;
  fhem &amp;quot;set m_schlauch -1&amp;quot;;&lt;br /&gt;
  fhem &amp;quot;set m_schrank auto&amp;quot;;&lt;br /&gt;
  fhem &amp;quot;set akt_treppe off&amp;quot;;&lt;br /&gt;
  fhem &amp;quot;set akt_eingang off&amp;quot;;&lt;br /&gt;
  fhem &amp;quot;set akt_esszimmer off&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== yahoo - Condition Codes ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Condition code	Beschreibung		Internes Mapping in: sub Twilight_getWeatherHorizon&lt;br /&gt;
	0	tornado			25&lt;br /&gt;
	1	tropical storm		25&lt;br /&gt;
	2	hurricane		25&lt;br /&gt;
	3	severe thunderstorms	25&lt;br /&gt;
	4	thunderstorms		20&lt;br /&gt;
	5	mixed rain and snow	10&lt;br /&gt;
	6	mixed rain and sleet	10&lt;br /&gt;
	7	mixed snow and sleet	10&lt;br /&gt;
	8	freezing drizzle	10&lt;br /&gt;
	9	drizzle			10&lt;br /&gt;
	10	freezing rain		10&lt;br /&gt;
	11	showers			7&lt;br /&gt;
	12	showers			7&lt;br /&gt;
	13	snow flurries		7&lt;br /&gt;
	14	light snow showers	5&lt;br /&gt;
	15	blowing snow		10&lt;br /&gt;
	16	snow			10&lt;br /&gt;
	17	hail			6&lt;br /&gt;
	18	sleet			6&lt;br /&gt;
	19	dust			6&lt;br /&gt;
	20	foggy			10&lt;br /&gt;
	21	haze			6&lt;br /&gt;
	22	smoky			6&lt;br /&gt;
	23	blustery		6&lt;br /&gt;
	24	windy			6&lt;br /&gt;
	25	cold			6&lt;br /&gt;
	26	cloudy			6&lt;br /&gt;
	27	mostly cloudy (night)	5&lt;br /&gt;
	28	mostly cloudy (day)	5&lt;br /&gt;
	29	partly cloudy (night)	3&lt;br /&gt;
	30	partly cloudy (day)	3&lt;br /&gt;
	31	clear (night)		0&lt;br /&gt;
	32	sunny			0&lt;br /&gt;
	33	fair (night)		0&lt;br /&gt;
	34	fair (day)		0&lt;br /&gt;
	35	mixed rain and hail	7&lt;br /&gt;
	36	hot			0&lt;br /&gt;
	37	isolated thunderstorms	15&lt;br /&gt;
	38	scattered thunderstorms	15&lt;br /&gt;
	39	scattered thunderstorms	15&lt;br /&gt;
	40	scattered showers	9&lt;br /&gt;
	41	heavy snow		15&lt;br /&gt;
	42	scattered snow showers	8&lt;br /&gt;
	43	heavy snow		5&lt;br /&gt;
	44	partly cloudy		12&lt;br /&gt;
	45	thundershowers		6&lt;br /&gt;
	46	snow showers		8&lt;br /&gt;
	47	isolated thundershowers	8&lt;br /&gt;
		not available		1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zusammenhang STATE und light ==&lt;br /&gt;
&lt;br /&gt;
STATE wird beim Twilight-Modul von 0 - 11 durchgezählt.&lt;br /&gt;
&lt;br /&gt;
0 -&amp;gt; vor astronomischen Aufgang, 1 -&amp;gt; vor nautischem Aufgang, 2 -&amp;gt; vor zivilem Aufgang, 3 -&amp;gt; vor Sonnenaufgang, 4 -&amp;gt; vor Indoor-Aufgang, 5 -&amp;gt; vor &amp;quot;Wetter-Aufgang&amp;quot;, 6 -&amp;gt; vor &amp;quot;Wetter-Untergang&amp;quot; (also den meisten Tag lang)&lt;br /&gt;
&lt;br /&gt;
Bis hierher ist light = STATE. Von nun an wird light wieder weniger (es wird ja dunkler) aber STATE schreitet vor, um Sonnenuntergänge von -aufgängen unterscheidbar zu machen.&lt;br /&gt;
&lt;br /&gt;
7 -&amp;gt; vor Indoor-Untergang, 8 -&amp;gt; vor Sonnenuntergang, 9 -&amp;gt; vor zivilem Untergang, 10 -&amp;gt; vor nautischem Untergang, 11 -&amp;gt; vor astronomischem Untergang&lt;br /&gt;
&lt;br /&gt;
Bitte auch bedenken, dass in der Nordhälfte Deutschlands die Sonne astronomisch im Sommer ca. 6 Wochen lang nicht untergeht, State wird also nicht alle Werte durchlaufen und light wird nie 0 sein.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Examples]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Twilight&amp;diff=28940</id>
		<title>Twilight</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Twilight&amp;diff=28940"/>
		<updated>2019-01-04T11:50:07Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Unbenutze Link-Sektion entfernt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hinweis|&#039;&#039;&#039;End of Live der Yahoo Weather API&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Da die Yahoo Weather API zum 03.01.2019 abgeschaltet wurde, kann &#039;&#039;&#039;Twilight&#039;&#039;&#039; aktuell keine Wetterdaten beziehen!}}&lt;br /&gt;
&lt;br /&gt;
{{Infobox Modul&lt;br /&gt;
|ModPurpose=Virtuelles Gerät zur Berechnung der Dämmerungszustände für eine gegebene Position&lt;br /&gt;
|ModType=h&lt;br /&gt;
&amp;lt;!-- |ModCategory=?? --&amp;gt;&lt;br /&gt;
&amp;lt;!-- |ModCmdRef={{Link2Forum|Topic=19922|LinkText=siehe Forum}} --&amp;gt;&lt;br /&gt;
|ModTechName=59_Twilight.pm&lt;br /&gt;
|ModForumArea=Unterstützende Dienste/Wettermodule&lt;br /&gt;
|ModOwner=igami ({{Link2FU|4106|Forum}} / [[Benutzer_Diskussion:Igami|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[Twilight]] ist ein Hilfsmodul, das für eine über Koordinaten spezifizierte Position diverse Dämmerungszustände, Zeiten und die Helligkeit berechnet und als Readings bereitstellt. Darüber hinaus werden auch, sofern spezifiziert, über die Yahoo Wetter-ID Wetterinformationen bereitgestellt bzw. in die Berechnungen mit einbezogen.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
Keine.&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
=== Define ===&lt;br /&gt;
:&amp;lt;code&amp;gt;define &amp;lt;name&amp;gt; Twilight &amp;lt;latitude&amp;gt; &amp;lt;longitude&amp;gt; [&amp;lt;indoor_horizon&amp;gt; [&amp;lt;Weather_Position&amp;gt;]]&amp;lt;/code&amp;gt;&lt;br /&gt;
Die Bedeutung der Parameter:&lt;br /&gt;
;latitude / longitude&lt;br /&gt;
:Geokoordinaten, für die die Werte berechnet werden sollen&lt;br /&gt;
;indoor_horizon&lt;br /&gt;
:Virtueller Horizont &lt;br /&gt;
;Weather_Position&lt;br /&gt;
:Yahoo Wetter-ID für den gewünschten Standort; der eingegebene Wert wird als &amp;quot;internal value&amp;quot; &#039;&#039;&#039;WEATHER&#039;&#039;&#039; gespeichert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Attribute ===&lt;br /&gt;
&lt;br /&gt;
=== Readings ===&lt;br /&gt;
Eine Auswahl der Readings, die das angelegte Twilight-Objekt enthält:&lt;br /&gt;
;sr*&lt;br /&gt;
:verschiedene Werte für den Sonnenaufgang (&amp;quot;&#039;&#039;&#039;s&#039;&#039;&#039;un&#039;&#039;&#039;r&#039;&#039;&#039;ise&amp;quot;): astronomisch, bürgerlich, nautisch, ...&lt;br /&gt;
;ss*&lt;br /&gt;
:verschiedene Werte für den Sonnenuntergang (&amp;quot;&#039;&#039;&#039;s&#039;&#039;&#039;un&#039;&#039;&#039;s&#039;&#039;&#039;et&amp;quot;): astronomisch, bürgerlich, nautisch, ...&lt;br /&gt;
;nextEvent&lt;br /&gt;
:Name des Ereignisses, das als nächstes eintreten wird (z.&amp;amp;nbsp;B. &amp;quot;ss_weather&amp;quot;)&lt;br /&gt;
;nextEventTime&lt;br /&gt;
:Zeitpunkt, zu dem das (unter &#039;&#039;nextEvent&#039;&#039; benannte) nächste Ereignis eintreten wird&lt;br /&gt;
;light&lt;br /&gt;
:ein errechneter Helligkeitswert mit den folgenden möglichen Werten (zwischen 0 und 6):&lt;br /&gt;
:;0&lt;br /&gt;
::Völlige Dunkelheit; relativer Sonnenstand zum Horizont: -18&amp;amp;deg;&lt;br /&gt;
:;1&lt;br /&gt;
::astronomische Dämmerung; relativer Sonnenstand zum Horizont: zwischen -12&amp;amp;deg; und -18&amp;amp;deg;&lt;br /&gt;
:;2&lt;br /&gt;
::nautische Dämmerung; relativer Sonnenstand zum Horizont: zwischen -6&amp;amp;deg; und -12&amp;amp;deg;&lt;br /&gt;
:;3&lt;br /&gt;
::bürgerliche Dämmerung; relativer Sonnenstand zum Horizont: zwischen 0&amp;amp;deg; und -6&amp;amp;deg;&lt;br /&gt;
:;4&lt;br /&gt;
::&amp;quot;indoor&amp;quot;-Dämmerung; Sonnenstand zwischen &#039;&#039;&#039;indoor_horizon&#039;&#039;&#039; (sofern der Wert ungleich Null ist) und 0&amp;amp;deg;&lt;br /&gt;
:;5&lt;br /&gt;
::&amp;quot;Wetter&amp;quot;-Dämmerung; Sonnenstand zwischen &#039;&#039;&#039;indoor_horizon&#039;&#039;&#039; und einem virtuellen Wetter-Horizont (abhängig von der Angabe einer &#039;&#039;&#039;Weather_position&#039;&#039;&#039;)&lt;br /&gt;
:;6&lt;br /&gt;
::&amp;quot;normales&amp;quot; Tageslicht&lt;br /&gt;
;azimuth&lt;br /&gt;
:Azimut; Horizontalwinkel des Sonnenstands (0&amp;amp;deg;=Norden, 180&amp;amp;deg;=Süden, usw.)&lt;br /&gt;
;elevation&lt;br /&gt;
:Höhe des Sonnenstands&lt;br /&gt;
;twilight&lt;br /&gt;
:Dämmerungswert, errechnet aus der Höhe des Sonnenstands. Der Wert geht von 0% bis 100% bei einem Sonnenstand zwischen -12&amp;amp;deg; und 6&amp;amp;deg; (also während der Dämmerungsphase).&lt;br /&gt;
&lt;br /&gt;
=== Funktionen ===&lt;br /&gt;
:&amp;lt;code&amp;gt;twilight($twilight, $reading, $min, $max)&amp;lt;/code&amp;gt;&lt;br /&gt;
Funktion im Modul, um bei der Dämmerungsberechnung Minimal-/Maximalwerte (&amp;quot;frühestens/spätestens&amp;quot;) spezifizieren und das Ergebnis beispielsweise in einem &amp;lt;code&amp;gt;at&amp;lt;/code&amp;gt; weiterverarbeiten zu können.&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiel(e) ==&lt;br /&gt;
=== Kurzes Beispiel ===&lt;br /&gt;
Anwendung der Funktion &#039;&#039;twilight&#039;&#039; zur Zeitsteuerung:&lt;br /&gt;
:&amp;lt;code&amp;gt;define morgens at *{twilight(&amp;quot;myTL&amp;quot;,&amp;quot;sr_indoor&amp;quot;,&amp;quot;7:30&amp;quot;,&amp;quot;9:00&amp;quot;)} set Rollo on&amp;lt;/code&amp;gt;&lt;br /&gt;
Dieses &#039;&#039;&#039;at&#039;&#039;&#039; wird morgens zum Zeitpunkt &#039;&#039;sr_indoor&#039;&#039; des Twilight Objekts &#039;&#039;myTL&#039;&#039; - aber frühestens um 7:30 und spätestens um 9:00 Uhr - dem Gerät &#039;&#039;Rollo&#039;&#039; einen &#039;&#039;on&#039;&#039;-Befehl schicken. Das Objekt &#039;&#039;myTL&#039;&#039; muss natürlich vorher mit (beispielsweise) &lt;br /&gt;
:&amp;lt;code&amp;gt;define myTL Twilight 44.444444 8.888888 ...&amp;lt;/code&amp;gt;&lt;br /&gt;
definiert worden sein.&lt;br /&gt;
&lt;br /&gt;
=== Ausführliches Beispiel ===&lt;br /&gt;
[[Twilight Anwendungsbeispiel]] mit detaillierten Erläuterungen&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Twilight&amp;diff=28939</id>
		<title>Twilight</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Twilight&amp;diff=28939"/>
		<updated>2019-01-04T11:46:51Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: Hinweis auf EOL der Yahoo Weather API&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hinweis|&#039;&#039;&#039;End of Live der Yahoo Weather API&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Da die Yahoo Weather API zum 03.01.2019 abgeschaltet wurde, kann &#039;&#039;&#039;Twilight&#039;&#039;&#039; aktuell keine Wetterdaten beziehen!}}&lt;br /&gt;
&lt;br /&gt;
{{Infobox Modul&lt;br /&gt;
|ModPurpose=Virtuelles Gerät zur Berechnung der Dämmerungszustände für eine gegebene Position&lt;br /&gt;
|ModType=h&lt;br /&gt;
&amp;lt;!-- |ModCategory=?? --&amp;gt;&lt;br /&gt;
&amp;lt;!-- |ModCmdRef={{Link2Forum|Topic=19922|LinkText=siehe Forum}} --&amp;gt;&lt;br /&gt;
|ModTechName=59_Twilight.pm&lt;br /&gt;
|ModForumArea=Unterstützende Dienste/Wettermodule&lt;br /&gt;
|ModOwner=igami ({{Link2FU|4106|Forum}} / [[Benutzer_Diskussion:Igami|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[Twilight]] ist ein Hilfsmodul, das für eine über Koordinaten spezifizierte Position diverse Dämmerungszustände, Zeiten und die Helligkeit berechnet und als Readings bereitstellt. Darüber hinaus werden auch, sofern spezifiziert, über die Yahoo Wetter-ID Wetterinformationen bereitgestellt bzw. in die Berechnungen mit einbezogen.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
Keine.&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
=== Define ===&lt;br /&gt;
:&amp;lt;code&amp;gt;define &amp;lt;name&amp;gt; Twilight &amp;lt;latitude&amp;gt; &amp;lt;longitude&amp;gt; [&amp;lt;indoor_horizon&amp;gt; [&amp;lt;Weather_Position&amp;gt;]]&amp;lt;/code&amp;gt;&lt;br /&gt;
Die Bedeutung der Parameter:&lt;br /&gt;
;latitude / longitude&lt;br /&gt;
:Geokoordinaten, für die die Werte berechnet werden sollen&lt;br /&gt;
;indoor_horizon&lt;br /&gt;
:Virtueller Horizont &lt;br /&gt;
;Weather_Position&lt;br /&gt;
:Yahoo Wetter-ID für den gewünschten Standort; der eingegebene Wert wird als &amp;quot;internal value&amp;quot; &#039;&#039;&#039;WEATHER&#039;&#039;&#039; gespeichert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Attribute ===&lt;br /&gt;
&lt;br /&gt;
=== Readings ===&lt;br /&gt;
Eine Auswahl der Readings, die das angelegte Twilight-Objekt enthält:&lt;br /&gt;
;sr*&lt;br /&gt;
:verschiedene Werte für den Sonnenaufgang (&amp;quot;&#039;&#039;&#039;s&#039;&#039;&#039;un&#039;&#039;&#039;r&#039;&#039;&#039;ise&amp;quot;): astronomisch, bürgerlich, nautisch, ...&lt;br /&gt;
;ss*&lt;br /&gt;
:verschiedene Werte für den Sonnenuntergang (&amp;quot;&#039;&#039;&#039;s&#039;&#039;&#039;un&#039;&#039;&#039;s&#039;&#039;&#039;et&amp;quot;): astronomisch, bürgerlich, nautisch, ...&lt;br /&gt;
;nextEvent&lt;br /&gt;
:Name des Ereignisses, das als nächstes eintreten wird (z.&amp;amp;nbsp;B. &amp;quot;ss_weather&amp;quot;)&lt;br /&gt;
;nextEventTime&lt;br /&gt;
:Zeitpunkt, zu dem das (unter &#039;&#039;nextEvent&#039;&#039; benannte) nächste Ereignis eintreten wird&lt;br /&gt;
;light&lt;br /&gt;
:ein errechneter Helligkeitswert mit den folgenden möglichen Werten (zwischen 0 und 6):&lt;br /&gt;
:;0&lt;br /&gt;
::Völlige Dunkelheit; relativer Sonnenstand zum Horizont: -18&amp;amp;deg;&lt;br /&gt;
:;1&lt;br /&gt;
::astronomische Dämmerung; relativer Sonnenstand zum Horizont: zwischen -12&amp;amp;deg; und -18&amp;amp;deg;&lt;br /&gt;
:;2&lt;br /&gt;
::nautische Dämmerung; relativer Sonnenstand zum Horizont: zwischen -6&amp;amp;deg; und -12&amp;amp;deg;&lt;br /&gt;
:;3&lt;br /&gt;
::bürgerliche Dämmerung; relativer Sonnenstand zum Horizont: zwischen 0&amp;amp;deg; und -6&amp;amp;deg;&lt;br /&gt;
:;4&lt;br /&gt;
::&amp;quot;indoor&amp;quot;-Dämmerung; Sonnenstand zwischen &#039;&#039;&#039;indoor_horizon&#039;&#039;&#039; (sofern der Wert ungleich Null ist) und 0&amp;amp;deg;&lt;br /&gt;
:;5&lt;br /&gt;
::&amp;quot;Wetter&amp;quot;-Dämmerung; Sonnenstand zwischen &#039;&#039;&#039;indoor_horizon&#039;&#039;&#039; und einem virtuellen Wetter-Horizont (abhängig von der Angabe einer &#039;&#039;&#039;Weather_position&#039;&#039;&#039;)&lt;br /&gt;
:;6&lt;br /&gt;
::&amp;quot;normales&amp;quot; Tageslicht&lt;br /&gt;
;azimuth&lt;br /&gt;
:Azimut; Horizontalwinkel des Sonnenstands (0&amp;amp;deg;=Norden, 180&amp;amp;deg;=Süden, usw.)&lt;br /&gt;
;elevation&lt;br /&gt;
:Höhe des Sonnenstands&lt;br /&gt;
;twilight&lt;br /&gt;
:Dämmerungswert, errechnet aus der Höhe des Sonnenstands. Der Wert geht von 0% bis 100% bei einem Sonnenstand zwischen -12&amp;amp;deg; und 6&amp;amp;deg; (also während der Dämmerungsphase).&lt;br /&gt;
&lt;br /&gt;
=== Funktionen ===&lt;br /&gt;
:&amp;lt;code&amp;gt;twilight($twilight, $reading, $min, $max)&amp;lt;/code&amp;gt;&lt;br /&gt;
Funktion im Modul, um bei der Dämmerungsberechnung Minimal-/Maximalwerte (&amp;quot;frühestens/spätestens&amp;quot;) spezifizieren und das Ergebnis beispielsweise in einem &amp;lt;code&amp;gt;at&amp;lt;/code&amp;gt; weiterverarbeiten zu können.&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiel(e) ==&lt;br /&gt;
=== Kurzes Beispiel ===&lt;br /&gt;
Anwendung der Funktion &#039;&#039;twilight&#039;&#039; zur Zeitsteuerung:&lt;br /&gt;
:&amp;lt;code&amp;gt;define morgens at *{twilight(&amp;quot;myTL&amp;quot;,&amp;quot;sr_indoor&amp;quot;,&amp;quot;7:30&amp;quot;,&amp;quot;9:00&amp;quot;)} set Rollo on&amp;lt;/code&amp;gt;&lt;br /&gt;
Dieses &#039;&#039;&#039;at&#039;&#039;&#039; wird morgens zum Zeitpunkt &#039;&#039;sr_indoor&#039;&#039; des Twilight Objekts &#039;&#039;myTL&#039;&#039; - aber frühestens um 7:30 und spätestens um 9:00 Uhr - dem Gerät &#039;&#039;Rollo&#039;&#039; einen &#039;&#039;on&#039;&#039;-Befehl schicken. Das Objekt &#039;&#039;myTL&#039;&#039; muss natürlich vorher mit (beispielsweise) &lt;br /&gt;
:&amp;lt;code&amp;gt;define myTL Twilight 44.444444 8.888888 ...&amp;lt;/code&amp;gt;&lt;br /&gt;
definiert worden sein.&lt;br /&gt;
&lt;br /&gt;
=== Ausführliches Beispiel ===&lt;br /&gt;
[[Twilight Anwendungsbeispiel]] mit detaillierten Erläuterungen&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Luftdaten.info/Feinstaub&amp;diff=28825</id>
		<title>Luftdaten.info/Feinstaub</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Luftdaten.info/Feinstaub&amp;diff=28825"/>
		<updated>2018-12-28T17:49:44Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Collect data from the Lufdaten.info project&lt;br /&gt;
|ModType=d&lt;br /&gt;
|ModCmdRef=LuftdatenInfo&lt;br /&gt;
|ModForumArea=Bastelecke&lt;br /&gt;
|ModFTopic=66674&lt;br /&gt;
|ModTechName=59_LuftdatenInfo.pm&lt;br /&gt;
|ModOwner=igami ({{Link2FU|4106|Forum}} / [[Benutzer:no_Legend|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&#039;&#039;&#039;LuftdatenInfo&#039;&#039;&#039; ist ein Modul, das Sensor-Daten des Projektes [http://luftdaten.info/ luftdaten.info] in FHEM abrufbar macht.&lt;br /&gt;
Es können lokale oder entfernte Sensoren abgefragt werden.&lt;br /&gt;
&lt;br /&gt;
== Sensor bauen ==&lt;br /&gt;
Der Bau eines Sensors wird auf der [http://luftdaten.info/feinstaubsensor-bauen/ Projektseite] beschrieben.&lt;br /&gt;
Die Kosten belaufen sich - je nach Bezugsquelle der einzelnen Bauteile und Bauform - auf ca. 30-50 €.&lt;br /&gt;
&lt;br /&gt;
Zwei kurze Videos zum Aufbau und Flashen des Sensor sind u.a. auf Youtube zu finden:&lt;br /&gt;
* [https://youtu.be/8oLCTeCfabU Luftdaten.info Feinstaubsensor selber bauen]&lt;br /&gt;
* [https://youtu.be/NK3E083WayM luftdaten.info Feinstaubsensor NodeMCU flashen unter Windows]&lt;br /&gt;
&lt;br /&gt;
== Datenschutz ==&lt;br /&gt;
In den  Standard-Einstellung der Software werden die Messwerte zu der Projektseite hochgeladen und dort, nach dem man den Maintainern des Projekts eine E-Mail mit weiteren Daten hat zukommen lassen, auf einer [http://deutschland.maps.luftdaten.info/ Karte] dargestellt. Dazu sind die &amp;quot;letzten Schritte&amp;quot; auf der [https://luftdaten.info/feinstaubsensor-bauen/ Anleitungsseite] ganz unten zu befolgen.&lt;br /&gt;
&lt;br /&gt;
Sollte keine Übertragung der Daten gewünscht sein, lassen sich die Geräte auch ausschließlich lokal betreiben und nicht von Fremden auslesen. Zumindest den Betreibern der Seite ist die Verknüpfung von Gerät zu Standort bekannt, ggf. lassen sich über die ermittelten Sensordaten auch genauere Standortdaten ermitteln.&lt;br /&gt;
&lt;br /&gt;
== Daten nutzen ==&lt;br /&gt;
&#039;&#039;&#039;LuftdatenInfo&#039;&#039;&#039; unterstützt folgende drei Betriebsmodi:&lt;br /&gt;
&lt;br /&gt;
=== Entfernte Abfrage ===&lt;br /&gt;
Mit &amp;lt;code&amp;gt;defmod &amp;lt;name&amp;gt; LuftdatenInfo remote &amp;lt;SensorID1&amp;gt; [&amp;lt;SensorID2&amp;gt; ..]&amp;lt;/code&amp;gt; können - auch fremde - entfernte Geräte von luftdaten.info abgefragt werden. Angelegt werden neben den Werten für PM2.5 und PM10 auch Ortsdaten (ungefähre Latitude, ungefähre Longitude und Postleitzahl + Stadt). Weitere Sensoren eines Gerätes kann man ggf. durch Hochzählen der SensorID einbinden, z.B. liefert die SensorID 17382 Feinstaubdaten, SensorID 17383 liefert darüber hinaus auch noch Temperatur, Luftdruck und Luftfeuchte zurück. Andere Sensoren als der Feinstaubsensor werden aktuell auf luftdaten.info nicht angezeigt, müssen also erprobt werden.&lt;br /&gt;
&lt;br /&gt;
=== Lokale Abfrage ===&lt;br /&gt;
Ein Gerät das Daten nicht an luftdaten.info oder eine der anderen Plattformen meldet, kann trotzdem lokal abgefragt werden. Dazu ist mit &amp;lt;code&amp;gt;defmod &amp;lt;name&amp;gt; LuftdatenInfo local &amp;lt;IP&amp;gt;&amp;lt;/code&amp;gt; das Gerät anzulegen. Es muss hier keine SensorID angegeben werden. Ohne weitere Einstellungen (&amp;lt;code&amp;gt;rawReadings&amp;lt;/code&amp;gt;) liefert der Sensor hier allerdings keine Sensordaten! Diese kann man über den Slave-Modus einbinden.&lt;br /&gt;
&lt;br /&gt;
=== Lokaler Slave-Modus ===&lt;br /&gt;
Im Slave-Modus können zu einem lokalen Gerät die einzelnen Sensoren als FHEM-Devices angelegt werden. Um den Slave-Modus nutzen zu können muss wie oben beschrieben ein lokales (Master-)Gerät angelegt werden. Einen Slave legt man mit &amp;lt;code&amp;gt;define &amp;lt;slave-name&amp;gt; LuftdatenInfo slave &amp;lt;master-name&amp;gt; [name-sensor1, name-sensor2]&amp;lt;/code&amp;gt; an. Die Namen der Sensoren enthält man in dem man &amp;lt;code&amp;gt;get &amp;lt;master-name&amp;gt; sensors&amp;lt;/code&amp;gt; ausführt. Das Ergebnis könnte eine Liste ähnlich wie diese sein:&lt;br /&gt;
&lt;br /&gt;
 BME680_air_quality&lt;br /&gt;
 BME680_humidity&lt;br /&gt;
 BME680_pressure&lt;br /&gt;
 BME680_pressure_nn&lt;br /&gt;
 BME680_quality_data&lt;br /&gt;
 BME680_temperature&lt;br /&gt;
 DHT22_humidity&lt;br /&gt;
 DHT22_temperature&lt;br /&gt;
 SDS011_P1&lt;br /&gt;
 SDS011_P2&lt;br /&gt;
 max_micro&lt;br /&gt;
 min_micro&lt;br /&gt;
 samples&lt;br /&gt;
 sensor_start_date&lt;br /&gt;
 sensor_start_time&lt;br /&gt;
 signal&lt;br /&gt;
&lt;br /&gt;
In diesem Gerät ist ein SDS011-Feinstaubsensor (vergebene Bezeichnung &#039;&#039;SDS011&#039;&#039;), ein BME680-Umweltsensor (vergebene Bezeichnung &#039;&#039;BME680&#039;&#039;) und ein DHT22-Luftfeuchte-/Temperatursensor (vergebene Bezeichnung &#039;&#039;DHT22&#039;&#039;) verbaut. &lt;br /&gt;
&lt;br /&gt;
Möchte man nun die Werte des BME680 in ein Slave-Gerät umleiten, muss man dieses wie folgt definieren:&lt;br /&gt;
 defmod &amp;lt;slave-bme680&amp;gt; LuftdatenInfo slave &amp;lt;master-name&amp;gt; BME680_air_quality BME680_humidity BME680_pressure BME680_pressure_nn BME680_quality_data BME680_temperature&lt;br /&gt;
&lt;br /&gt;
Die anderen gelisteten &amp;quot;Sensoren&amp;quot; sind keine, sondern Datenpunkte:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Wert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| max_micro || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| min_micro || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| sensor_start_date || Datum an dem das Gerät gestartet wurde&lt;br /&gt;
|-&lt;br /&gt;
| sensor_start_time || Zeitpunkt zu dem das Gerät gestartet wurde&lt;br /&gt;
|-&lt;br /&gt;
| signal || Wifi-Leistungspegel (Signalstärke) in dBm&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Other Components]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Luftdaten.info/Feinstaub&amp;diff=28824</id>
		<title>Luftdaten.info/Feinstaub</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Luftdaten.info/Feinstaub&amp;diff=28824"/>
		<updated>2018-12-28T17:47:15Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Collect data from the Lufdaten.info project&lt;br /&gt;
|ModType=d&lt;br /&gt;
|ModCmdRef=LuftdatenInfo&lt;br /&gt;
|ModForumArea=Bastelecke&lt;br /&gt;
|ModFTopic=66674&lt;br /&gt;
|ModTechName=59_LuftdatenInfo.pm&lt;br /&gt;
|ModOwner=igami ({{Link2FU|4106|Forum}} / [[Benutzer:no_Legend|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&#039;&#039;&#039;LuftdatenInfo&#039;&#039;&#039; ist ein Modul, das die Daten des Projektes [http://luftdaten.info/ luftdaten.info] in FHEM abrufbar macht.&lt;br /&gt;
Es können lokale oder entfernte Sensoren abgefragt werden.&lt;br /&gt;
&lt;br /&gt;
== Sensor bauen ==&lt;br /&gt;
Der Bau eines Sensors wird auf der [http://luftdaten.info/feinstaubsensor-bauen/ Projektseite] beschrieben.&lt;br /&gt;
Die Kosten belaufen sich - je nach Bezugsquelle der einzelnen Bauteile und Bauform - auf ca. 30-50 €.&lt;br /&gt;
&lt;br /&gt;
Zwei kurze Videos zum Aufbau und Flashen des Sensor sind u.a. auf Youtube zu finden:&lt;br /&gt;
* [https://youtu.be/8oLCTeCfabU Luftdaten.info Feinstaubsensor selber bauen]&lt;br /&gt;
* [https://youtu.be/NK3E083WayM luftdaten.info Feinstaubsensor NodeMCU flashen unter Windows]&lt;br /&gt;
&lt;br /&gt;
== Datenschutz ==&lt;br /&gt;
In den  Standard-Einstellung der Software werden die Messwerte zu der Projektseite hochgeladen und dort, nach dem man den Maintainern des Projekts eine E-Mail mit weiteren Daten hat zukommen lassen, auf einer [http://deutschland.maps.luftdaten.info/ Karte] dargestellt. Dazu sind die &amp;quot;letzten Schritte&amp;quot; auf der [https://luftdaten.info/feinstaubsensor-bauen/ Anleitungsseite] ganz unten zu befolgen.&lt;br /&gt;
&lt;br /&gt;
Sollte keine Übertragung der Daten gewünscht sein, lassen sich die Geräte auch ausschließlich lokal betreiben und nicht von Fremden auslesen. Zumindest den Betreibern der Seite ist die Verknüpfung von Gerät zu Standort bekannt, ggf. lassen sich über die ermittelten Sensordaten auch genauere Standortdaten ermitteln.&lt;br /&gt;
&lt;br /&gt;
== Daten nutzen ==&lt;br /&gt;
&#039;&#039;&#039;LuftdatenInfo&#039;&#039;&#039; unterstützt folgende drei Betriebsmodi:&lt;br /&gt;
&lt;br /&gt;
=== Entfernte Abfrage ===&lt;br /&gt;
Mit &amp;lt;code&amp;gt;defmod &amp;lt;name&amp;gt; LuftdatenInfo remote &amp;lt;SensorID1&amp;gt; [&amp;lt;SensorID2&amp;gt; ..]&amp;lt;/code&amp;gt; können - auch fremde - entfernte Geräte von luftdaten.info abgefragt werden. Angelegt werden neben den Werten für PM2.5 und PM10 auch Ortsdaten (ungefähre Latitude, ungefähre Longitude und Postleitzahl + Stadt). Weitere Sensoren eines Gerätes kann man ggf. durch Hochzählen der SensorID einbinden, z.B. liefert die SensorID 17382 Feinstaubdaten, SensorID 17383 liefert darüber hinaus auch noch Temperatur, Luftdruck und Luftfeuchte zurück. Andere Sensoren als der Feinstaubsensor werden aktuell auf luftdaten.info nicht angezeigt, müssen also erprobt werden.&lt;br /&gt;
&lt;br /&gt;
=== Lokale Abfrage ===&lt;br /&gt;
Ein Gerät das Daten nicht an luftdaten.info oder eine der anderen Plattformen meldet, kann trotzdem lokal abgefragt werden. Dazu ist mit &amp;lt;code&amp;gt;defmod &amp;lt;name&amp;gt; LuftdatenInfo local &amp;lt;IP&amp;gt;&amp;lt;/code&amp;gt; das Gerät anzulegen. Es muss hier keine SensorID angegeben werden. Ohne weitere Einstellungen (&amp;lt;code&amp;gt;rawReadings&amp;lt;/code&amp;gt;) liefert der Sensor hier allerdings keine Sensordaten! Diese kann man über den Slave-Modus einbinden.&lt;br /&gt;
&lt;br /&gt;
=== Lokaler Slave-Modus ===&lt;br /&gt;
Im Slave-Modus können zu einem lokalen Gerät die einzelnen Sensoren als FHEM-Devices angelegt werden. Um den Slave-Modus nutzen zu können muss wie oben beschrieben ein lokales (Master-)Gerät angelegt werden. Einen Slave legt man mit &amp;lt;code&amp;gt;define &amp;lt;slave-name&amp;gt; LuftdatenInfo slave &amp;lt;master-name&amp;gt; [name-sensor1, name-sensor2]&amp;lt;/code&amp;gt; an. Die Namen der Sensoren enthält man in dem man &amp;lt;code&amp;gt;get &amp;lt;master-name&amp;gt; sensors&amp;lt;/code&amp;gt; ausführt. Das Ergebnis könnte eine Liste ähnlich wie diese sein:&lt;br /&gt;
&lt;br /&gt;
 BME680_air_quality&lt;br /&gt;
 BME680_humidity&lt;br /&gt;
 BME680_pressure&lt;br /&gt;
 BME680_pressure_nn&lt;br /&gt;
 BME680_quality_data&lt;br /&gt;
 BME680_temperature&lt;br /&gt;
 DHT22_humidity&lt;br /&gt;
 DHT22_temperature&lt;br /&gt;
 SDS011_P1&lt;br /&gt;
 SDS011_P2&lt;br /&gt;
 max_micro&lt;br /&gt;
 min_micro&lt;br /&gt;
 samples&lt;br /&gt;
 sensor_start_date&lt;br /&gt;
 sensor_start_time&lt;br /&gt;
 signal&lt;br /&gt;
&lt;br /&gt;
In diesem Gerät ist ein SDS011-Feinstaubsensor (vergebene Bezeichnung &#039;&#039;SDS011&#039;&#039;), ein BME680-Umweltsensor (vergebene Bezeichnung &#039;&#039;BME680&#039;&#039;) und ein DHT22-Luftfeuchte-/Temperatursensor (vergebene Bezeichnung &#039;&#039;DHT22&#039;&#039;) verbaut. &lt;br /&gt;
&lt;br /&gt;
Möchte man nun die Werte des BME680 in ein Slave-Gerät umleiten, muss man dieses wie folgt definieren:&lt;br /&gt;
 defmod &amp;lt;slave-bme680&amp;gt; LuftdatenInfo slave &amp;lt;master-name&amp;gt; BME680_air_quality BME680_humidity BME680_pressure BME680_pressure_nn BME680_quality_data BME680_temperature&lt;br /&gt;
&lt;br /&gt;
Die anderen gelisteten &amp;quot;Sensoren&amp;quot; sind keine, sondern Datenpunkte:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Wert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| max_micro || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| min_micro || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| sensor_start_date || Datum an dem das Gerät gestartet wurde&lt;br /&gt;
|-&lt;br /&gt;
| sensor_start_time || Zeitpunkt zu dem das Gerät gestartet wurde&lt;br /&gt;
|-&lt;br /&gt;
| signal || Wifi-Leistungspegel (Signalstärke) in dBm&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Other Components]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Luftdaten.info/Feinstaub&amp;diff=28823</id>
		<title>Luftdaten.info/Feinstaub</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Luftdaten.info/Feinstaub&amp;diff=28823"/>
		<updated>2018-12-28T17:46:59Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Collect data from the Lufdaten.info project&lt;br /&gt;
|ModType=d&lt;br /&gt;
|ModCmdRef=LuftdatenInfo&lt;br /&gt;
|ModForumArea=Bastelecke&lt;br /&gt;
|ModFTopic=66674&lt;br /&gt;
|ModTechName=59_LuftdatenInfo.pm&lt;br /&gt;
|ModOwner=igami ({{Link2FU|4106|Forum}} / [[Benutzer:no_Legend|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&#039;&#039;&#039;LuftdatenInfo&#039;&#039;&#039; ist ein Modul, das die Daten des Projektes [http://luftdaten.info/ luftdaten.info] in FHEM abrufbar macht.&lt;br /&gt;
Es können lokale oder entfernte Sensoren abgefragt werden.&lt;br /&gt;
&lt;br /&gt;
== Sensor bauen ==&lt;br /&gt;
Der Bau eines Sensors wird auf der [http://luftdaten.info/feinstaubsensor-bauen/ Projektseite] beschrieben.&lt;br /&gt;
Die Kosten belaufen sich - je nach Bezugsquelle der einzelnen Bauteile und Bauform - auf ca. 30-50 €.&lt;br /&gt;
&lt;br /&gt;
Zwei kurze Videos zum Aufbau und Flashen des Sensor sind u.a. auf Youtube zu finden:&lt;br /&gt;
* [https://youtu.be/8oLCTeCfabU Luftdaten.info Feinstaubsensor selber bauen]&lt;br /&gt;
* [https://youtu.be/NK3E083WayM luftdaten.info Feinstaubsensor NodeMCU flashen unter Windows]&lt;br /&gt;
&lt;br /&gt;
== Datenschutz ==&lt;br /&gt;
In den  Standard-Einstellung der Software werden die Messwerte zu der Projektseite hochgeladen und dort, nach dem man den Maintainern des Projekts eine E-Mail mit weiteren Daten hat zukommen lassen, auf einer [http://deutschland.maps.luftdaten.info/ Karte] dargestellt. Dazu sind die &amp;quot;letzten Schritte&amp;quot; auf der [https://luftdaten.info/feinstaubsensor-bauen/ Anleitungsseite] ganz unten zu befolgen.&lt;br /&gt;
&lt;br /&gt;
Sollte keine Übertragung der Daten gewünscht sein, lassen sich die Geräte auch ausschließlich lokal betreiben und nicht von Fremden auslesen. Zumindest den Betreibern der Seite ist die Verknüpfung von Gerät zu Standort bekannt, ggf. lassen sich über die ermittelten Sensordaten auch genauere Standortdaten ermitteln.&lt;br /&gt;
&lt;br /&gt;
== Daten nutzen ==&lt;br /&gt;
&#039;&#039;&#039;LuftdatenInfo&#039;&#039;&#039; unterstützt folgende drei Betriebsmodi:&lt;br /&gt;
&lt;br /&gt;
=== Entfernte Abfrage ===&lt;br /&gt;
Mit &amp;lt;code&amp;gt;defmod &amp;lt;name&amp;gt; LuftdatenInfo remote &amp;lt;SensorID1&amp;gt; [&amp;lt;SensorID2&amp;gt; ..]&amp;lt;/code&amp;gt; können - auch fremde - entfernte Geräte von luftdaten.info abgefragt werden. Angelegt werden neben den Werten für PM2.5 und PM10 auch Ortsdaten (ungefähre Latitude, ungefähre Longitude und Postleitzahl + Stadt). Weitere Sensoren eines Gerätes kann man ggf. durch Hochzählen der SensorID einbinden, z.B. liefert die SensorID 17382 Feinstaubdaten, SensorID 17383 liefert darüber hinaus auch noch Temperatur, Luftdruck und Luftfeuchte zurück. Andere Sensoren als der Feinstaubsensor werden aktuell auf luftdaten.info nicht angezeigt, müssen also erprobt werden.&lt;br /&gt;
&lt;br /&gt;
=== Lokale Abfrage ===&lt;br /&gt;
Ein Gerät das Daten nicht an luftdaten.info oder eine der anderen Plattformen meldet, kann trotzdem lokal abgefragt werden. Dazu ist mit &amp;lt;code&amp;gt;defmod &amp;lt;name&amp;gt; LuftdatenInfo local &amp;lt;IP&amp;gt;&amp;lt;/code&amp;gt; das Gerät anzulegen. Es muss hier keine SensorID angegeben werden. Ohne weitere Einstellungen (&amp;lt;code&amp;gt;rawReadings&amp;lt;/code&amp;gt;) liefert der Sensor hier allerdings keine Sensordaten! Diese kann man über den Slave-Modus einbinden.&lt;br /&gt;
&lt;br /&gt;
=== Lokaler Slave-Modus ===&lt;br /&gt;
Im Slave-Modus können zu einem lokalen Gerät die einzelnen Sensoren als FHEM-Devices angelegt werden. Um den Slave-Modus nutzen zu können muss wie oben beschrieben ein lokales (Master-)Gerät angelegt werden. Einen Slave legt man mit &amp;lt;code&amp;gt;define &amp;lt;slave-name&amp;gt; LuftdatenInfo slave &amp;lt;master-name&amp;gt; [name-sensor1, name-sensor2]&amp;lt;/code&amp;gt; an. Die Namen der Sensoren enthält man in dem man &amp;lt;code&amp;gt;get &amp;lt;master-name&amp;gt; sensors&amp;lt;/code&amp;gt; ausführt. Das Ergebnis könnte eine Liste ähnlich wie diese sein:&lt;br /&gt;
&lt;br /&gt;
 BME680_air_quality&lt;br /&gt;
 BME680_humidity&lt;br /&gt;
 BME680_pressure&lt;br /&gt;
 BME680_pressure_nn&lt;br /&gt;
 BME680_quality_data&lt;br /&gt;
 BME680_temperature&lt;br /&gt;
 DHT22_humidity&lt;br /&gt;
 DHT22_temperature&lt;br /&gt;
 SDS011_P1&lt;br /&gt;
 SDS011_P2&lt;br /&gt;
 max_micro&lt;br /&gt;
 min_micro&lt;br /&gt;
 samples&lt;br /&gt;
 sensor_start_date&lt;br /&gt;
 sensor_start_time&lt;br /&gt;
 signal&lt;br /&gt;
&lt;br /&gt;
In diesem Gerät ist ein SDS011-Feinstaubsensor (vergebene Bezeichnung &#039;&#039;SDS011&#039;&#039;), ein BME680-Umweltsensor (vergebene Bezeichnung &#039;&#039;BME680&#039;&#039;) und ein DHT22-Luftfeuchte-/Temperatursensor (vergebene Bezeichnung &#039;&#039;DHT22&#039;&#039;) verbaut. &lt;br /&gt;
&lt;br /&gt;
Möchte man nun die Werte des BME680 in ein Slave-Gerät umleiten, muss man dieses wie folgt definieren:&lt;br /&gt;
 defmod &amp;lt;slave-bme680&amp;gt; LuftdatenInfo slave &amp;lt;master-name&amp;gt; BME680_air_quality BME680_humidity BME680_pressure BME680_pressure_nn BME680_quality_data BME680_temperature&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die anderen gelisteten &amp;quot;Sensoren&amp;quot; sind keine, sondern Datenpunkte:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Wert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| max_micro || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| min_micro || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| sensor_start_date || Datum an dem das Gerät gestartet wurde&lt;br /&gt;
|-&lt;br /&gt;
| sensor_start_time || Zeitpunkt zu dem das Gerät gestartet wurde&lt;br /&gt;
|-&lt;br /&gt;
| signal || Wifi-Leistungspegel (Signalstärke) in dBm&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Other Components]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Luftdaten.info/Feinstaub&amp;diff=28822</id>
		<title>Luftdaten.info/Feinstaub</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Luftdaten.info/Feinstaub&amp;diff=28822"/>
		<updated>2018-12-28T17:44:52Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Collect data from the Lufdaten.info project&lt;br /&gt;
|ModType=d&lt;br /&gt;
|ModCmdRef=LuftdatenInfo&lt;br /&gt;
|ModForumArea=Bastelecke&lt;br /&gt;
|ModFTopic=66674&lt;br /&gt;
|ModTechName=59_LuftdatenInfo.pm&lt;br /&gt;
|ModOwner=igami ({{Link2FU|4106|Forum}} / [[Benutzer:no_Legend|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dieser Artikel befindet sich noch im Aufbau.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LuftdatenInfo&#039;&#039;&#039; ist ein Modul, das die Daten des Projektes http://luftdaten.info/ in FHEM abrufbar macht.&lt;br /&gt;
Es können lokale oder entfernte Sensoren abgefragt werden.&lt;br /&gt;
&lt;br /&gt;
== Sensor bauen ==&lt;br /&gt;
Der Bau eines Sensors wird auf der [http://luftdaten.info/feinstaubsensor-bauen/ Projektseite] beschrieben.&lt;br /&gt;
Die Kosten belaufen sich - je nach Bezugsquelle der einzelnen Bauteile und Bauform - auf ca. 30-50 €.&lt;br /&gt;
&lt;br /&gt;
Zwei kurze Videos zum Aufbau und Flashen des Sensor sind u.a. auf Youtube zu finden:&lt;br /&gt;
* [https://youtu.be/8oLCTeCfabU Luftdaten.info Feinstaubsensor selber bauen]&lt;br /&gt;
* [https://youtu.be/NK3E083WayM luftdaten.info Feinstaubsensor NodeMCU flashen unter Windows]&lt;br /&gt;
&lt;br /&gt;
== Datenschutz ==&lt;br /&gt;
In den  Standard-Einstellung der Software werden die Messwerte zu der Projektseite hochgeladen und dort, nach dem man den Maintainern des Projekts eine E-Mail mit weiteren Daten hat zukommen lassen, auf einer [http://deutschland.maps.luftdaten.info/ Karte] dargestellt. Dazu sind die &amp;quot;letzten Schritte&amp;quot; auf der [https://luftdaten.info/feinstaubsensor-bauen/ Anleitungsseite] ganz unten zu befolgen.&lt;br /&gt;
&lt;br /&gt;
Sollte keine Übertragung der Daten gewünscht sein, lassen sich die Geräte auch ausschließlich lokal betreiben und nicht von Fremden auslesen. Zumindest den Betreibern der Seite ist die Verknüpfung von Gerät zu Standort bekannt, ggf. lassen sich über die ermittelten Sensordaten auch genauere Standortdaten ermitteln.&lt;br /&gt;
&lt;br /&gt;
== Daten nutzen ==&lt;br /&gt;
&#039;&#039;&#039;LuftdatenInfo&#039;&#039;&#039; unterstützt folgende drei Betriebsmodi:&lt;br /&gt;
&lt;br /&gt;
=== Entfernte Abfrage ===&lt;br /&gt;
Mit &amp;lt;code&amp;gt;defmod &amp;lt;name&amp;gt; LuftdatenInfo remote &amp;lt;SensorID1&amp;gt; [&amp;lt;SensorID2&amp;gt; ..]&amp;lt;/code&amp;gt; können - auch fremde - entfernte Geräte von luftdaten.info abgefragt werden. Angelegt werden neben den Werten für PM2.5 und PM10 auch Ortsdaten (ungefähre Latitude, ungefähre Longitude und Postleitzahl + Stadt). Weitere Sensoren eines Gerätes kann man ggf. durch Hochzählen der SensorID einbinden, z.B. liefert die SensorID 17382 Feinstaubdaten, SensorID 17383 liefert darüber hinaus auch noch Temperatur, Luftdruck und Luftfeuchte zurück. Andere Sensoren als der Feinstaubsensor werden aktuell auf luftdaten.info nicht angezeigt, müssen also erprobt werden.&lt;br /&gt;
&lt;br /&gt;
=== Lokale Abfrage ===&lt;br /&gt;
Ein Gerät das Daten nicht an luftdaten.info oder eine der anderen Plattformen meldet, kann trotzdem lokal abgefragt werden. Dazu ist mit &amp;lt;code&amp;gt;defmod &amp;lt;name&amp;gt; LuftdatenInfo local &amp;lt;IP&amp;gt;&amp;lt;/code&amp;gt; das Gerät anzulegen. Es muss hier keine SensorID angegeben werden. Ohne weitere Einstellungen (&amp;lt;code&amp;gt;rawReadings&amp;lt;/code&amp;gt;) liefert der Sensor hier allerdings keine Sensordaten! Diese kann man über den Slave-Modus einbinden.&lt;br /&gt;
&lt;br /&gt;
=== Lokaler Slave-Modus ===&lt;br /&gt;
Im Slave-Modus können zu einem lokalen Gerät die einzelnen Sensoren als FHEM-Devices angelegt werden. Um den Slave-Modus nutzen zu können muss wie oben beschrieben ein lokales (Master-)Gerät angelegt werden. Einen Slave legt man mit &amp;lt;code&amp;gt;define &amp;lt;slave-name&amp;gt; LuftdatenInfo slave &amp;lt;master-name&amp;gt; [name-sensor1, name-sensor2]&amp;lt;/code&amp;gt; an. Die Namen der Sensoren enthält man in dem man &amp;lt;code&amp;gt;get &amp;lt;master-name&amp;gt; sensors&amp;lt;/code&amp;gt; ausführt. Das Ergebnis könnte eine Liste ähnlich wie diese sein:&lt;br /&gt;
&lt;br /&gt;
 BME680_air_quality&lt;br /&gt;
 BME680_humidity&lt;br /&gt;
 BME680_pressure&lt;br /&gt;
 BME680_pressure_nn&lt;br /&gt;
 BME680_quality_data&lt;br /&gt;
 BME680_temperature&lt;br /&gt;
 DHT22_humidity&lt;br /&gt;
 DHT22_temperature&lt;br /&gt;
 SDS011_P1&lt;br /&gt;
 SDS011_P2&lt;br /&gt;
 max_micro&lt;br /&gt;
 min_micro&lt;br /&gt;
 samples&lt;br /&gt;
 sensor_start_date&lt;br /&gt;
 sensor_start_time&lt;br /&gt;
 signal&lt;br /&gt;
&lt;br /&gt;
In diesem Gerät ist ein SDS011-Feinstaubsensor (vergebene Bezeichnung &#039;&#039;SDS011&#039;&#039;), ein BME680-Umweltsensor (vergebene Bezeichnung &#039;&#039;BME680&#039;&#039;) und ein DHT22-Luftfeuchte-/Temperatursensor (vergebene Bezeichnung &#039;&#039;DHT22&#039;&#039;) verbaut. &lt;br /&gt;
&lt;br /&gt;
Möchte man nun die Werte des BME680 in ein Slave-Gerät umleiten, muss man dieses wie folgt definieren:&lt;br /&gt;
 defmod &amp;lt;slave-bme680&amp;gt; LuftdatenInfo slave &amp;lt;master-name&amp;gt; BME680_air_quality BME680_humidity BME680_pressure BME680_pressure_nn BME680_quality_data BME680_temperature&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die anderen gelisteten &amp;quot;Sensoren&amp;quot; sind keine, sondern Datenpunkte:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Wert !! Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| max_micro || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| min_micro || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| sensor_start_date || Datum an dem das Gerät gestartet wurde&lt;br /&gt;
|-&lt;br /&gt;
| sensor_start_time || Zeitpunkt zu dem das Gerät gestartet wurde&lt;br /&gt;
|-&lt;br /&gt;
| signal || Wifi-Leistungspegel (Signalstärke) in dBm&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Other Components]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Energiesparende_Schimmelbek%C3%A4mpfung_/_Luftentfeuchtung_in_kritischen_R%C3%A4umen&amp;diff=28676</id>
		<title>Energiesparende Schimmelbekämpfung / Luftentfeuchtung in kritischen Räumen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Energiesparende_Schimmelbek%C3%A4mpfung_/_Luftentfeuchtung_in_kritischen_R%C3%A4umen&amp;diff=28676"/>
		<updated>2018-12-14T17:49:57Z</updated>

		<summary type="html">&lt;p&gt;ChristophMorrison: /* Alles zusammenpacken */  Link gefixt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Voraussetzungen / Benötigte Technik==&lt;br /&gt;
* Einen Raum mit kalten Wandstellen&lt;br /&gt;
* Innentemperatursensor und Luftfeuchtesensor im betroffenen Raum (z.B. [[HomeMatic]] [[HM-CC-RT-DN Funk-Heizkörperthermostat|Wandthermostat]])&lt;br /&gt;
* Außentemperatursensor (oder notfalls die aktuellen Wetterdaten von Yahoo und Co.)&lt;br /&gt;
* Infrarotthermometer (ohne Anbindung an FHEM und nur leihweise für ein paar Tage, wird nur zum Einrichten benötigt)&lt;br /&gt;
* Luftentfeuchter, der sich z.B. per HomeMatic-Zwischenstecker an/ausschalten lässt (optional, man kann sich natürlich auch nur Warnungen ausgeben lassen)&lt;br /&gt;
&lt;br /&gt;
==Ausgangslage==&lt;br /&gt;
Schimmel will trinken, um Wachsen zu können. Möchte man einschätzen, ob in einem Raum Schimmelgefahr besteht, kann man das mit FHEM-Bordmitteln über das Taupunkt-Modul [[dewpoint]] machen. Wenn der Taupunkt der Raumluft über der Oberflächentemperatur der Wand liegt, dann kondensiert das Wasser und es schimmelt. Man muss also nur die Taupunkttemperatur Td(Raumtemperatur, rel. Raumluftfeuchte) mit der Wandtemperatur vergleichen. Hierzu muss man natürlich die Wandtemperatur (an der kältesten Stelle, hier kondensiert das Wasser aus der Luft zuerst) ersteinmal kennen. Das Problem haben wir aber immer, egal wie wir es anstellen - dazu später mehr.&lt;br /&gt;
&lt;br /&gt;
Diese Variante per Taupunkt ist aber nur die halbe Miete: Laut verschiedenen Quellen wächst mancher Schimmelpilz schon viel früher - ohne kondensierten, flüssigen Wasserfilm, allein durch eine hohe relative Luftfeuchte von über 70% (manche Quellen sagen 80%). Hat eine Oberfläche genau die Taupunkttemperatur der Raumluft, ist die relative Luftfeuchte dort bei 100% - also deutlich über den gefährlichen 70-80%, so dass sich Schimmel dort schon recht wohlfühlen sollte. &lt;br /&gt;
&lt;br /&gt;
Nun könnte man entweder ein paar Grad &amp;quot;Sicherheitsmarge&amp;quot; auf den Taupunkt addieren. Prima. Nur wie groß sollte unsere Sicherheitsmarge genau sein, ohne den Raum mit z.B. 200-300 Watt sehr energieintensiv zu viel zu entfeuchten? Dann vielleicht doch ganz simpel ansetzen und in FHEM definieren: Schimmelwarnung ausgeben oder Luftentfeuchter anschalten bei über 70% Raumluftfeuchte. Punkt. Dazu könnte man dann bequem z.B. einen Homematic-Raumthermostaten nehmen und dessen Sensorwert für die Luftfeuchtigkeit auf Überschreitung der 70%-Marke prüfen - so tun das sicher auch viele. Aber das kann wie in meinem Fall - die Wände sind an einigen Stellen kälter als die Raumluft - genau wie die Taupunkt-Methode jämmerlich schiefgehen.&lt;br /&gt;
&lt;br /&gt;
Das Problem dabei ist nämlich, dass die Luft nicht einfach schlagartig an Flächen auskondensiert, die kälter sind als der Taupunkt. Die relative Luftfeuchte steigt mit jedem Grad weniger kontinuierlich an. Und dieser Effekt ist je nach Bausubstanz und &amp;quot;Wandkälte&amp;quot; durchaus erheblich. So ist die 70%-Marke an der Wand schon mitunter bei einer Luftfeuchtigkeit im Raum von 55% oder gar weniger überschritten. Eine „Sicherheitsmarge“ muss  dann schon ganz schön groß ausfallen - und der Raum z.B. dauerhaft auf 50% entfeuchtet werden. Oh je, die Stromrechnung, denn das ist an wärmeren Tagen, wo die Wände vielleicht nur 2 Grad kälter sind als die Luft im Raum, viel zu viel. Bei mir liegt z.B. in den Fensterzargen die (mit einem Infrarotthermometer gemessene) Oberflächentemperatur an kalten Tagen mit Temperaturen unter dem Gefrierpunkt manchmal 10 Grad unter der Raumtemperatur - man spricht bei solchen nicht immer behebbaren Baumängeln von sog. „Kältebrücken“. Das wirkt sich an solchen Tagen schon extrem auf die relative Luftfeuchte aus und ließ bei mir den Schimmel wachsen. &lt;br /&gt;
&lt;br /&gt;
Nur wie stark ist diese Auswirkung denn nun genau? Das hängt wie gesagt von der Differenz zwischen Raumtemperatur und Wandtemperatur (und damit der Außentemperatur) ab - je größer die Differenz, desto stärker der Feuchteanstieg in Wandnähe. Leider ist der Zusammenhang aber nicht linear, so dass man das ausrechnen muss. Da ich das nirgends fertig gefunden habe, habe ich [http://www.wetterochs.de/wetter/feuchte.html hier] die nötigen Formeln gefunden, umgestellt und in folgende Funktion für die 99_myUtils.pm gegossen:&lt;br /&gt;
&lt;br /&gt;
 sub shiftRelHumidity($$$)&lt;br /&gt;
 # Uses a pair of relative humidity and temperature ($r1, $T1) to calculate the relative &lt;br /&gt;
 # humidity on spots with same absolute humidity of the air but different temperature $T2.&lt;br /&gt;
 #&lt;br /&gt;
 # Useful to calculate the relative humidity near the surface of cold walls. Therefore, use the rel. &lt;br /&gt;
 # humidity of the room ($r1 in percent), the room Temperature ($T2 in degrees of C) and the temperature&lt;br /&gt;
 # of the surface of the wall ($T2 in degrees of C). Returns the rel. humidity on the surface in pct then.&lt;br /&gt;
 {&lt;br /&gt;
   my ($T1, $r1, $T2) = @_;&lt;br /&gt;
   my $r2 =  ($r1 * 10**((7.62*$T1)/(234.175+$T1))*(273.15+$T2)) / ( 10**((7.62*$T2)/(234.175+$T2))*(273.15+$T1));&lt;br /&gt;
   return $r2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wen die Herleitung interessiert und wer nachrechnen möchte, ob ich mich vertan habe, der möge es mich wissen lassen. Einem Vergleich mit der Berechnung [http://wetterstationwien22.at/html/relative-luftfeuchte--erwarmung-.html dieser Seite] hält die Formel aber einigermaßen Stand.&lt;br /&gt;
&lt;br /&gt;
Wir können hiermit nun also in Abhängigkeit von der Raumtemperatur, der relativen Luftfeuchte des Raumes und der Oberflächentemperatur der Wand die relative Luftfeuchte in Wandnähe ziemlich genau ausrechnen. Und dann das Ganze in ein UserReading packen und unseren Luftentfeuchter danach regeln - oder unsere Schimmelwarnung versenden, mit dem Hinweis, dass vielleicht mal gelüftet oder der Raum mehr beheizt werden müsste (beides kann helfen - das ist aber ein anderes Thema und will ich hier nicht weiter behandeln). Da gibt es vorher aber nach wie vor noch ein mittelprächtiges Problem: woher nehmen wir die Wandtemperatur?&lt;br /&gt;
&lt;br /&gt;
==Wandtemperatur ermitteln==&lt;br /&gt;
Perfekt wäre natürlich, einen Oberflächentemperatursensor an der kältesten Stelle der Wand zu platzieren und den Wert direkt zu messen. Wer es ganz genau machen will und seinen Luftentfeuchter wirklich sparsam einsetzen will, der sollte das vielleicht auch so tun - dann kann man aber dort auch gleich die Luftfeuchtigkeit oder Oberflächenfeuchtigkeit messen. Meistens ist das aber relativ umständlich, unhübsch und kostet auch noch Geld für zusätzliche Sensoren.&lt;br /&gt;
&lt;br /&gt;
Was sich bei mir aber auch als ziemlich genau herausgestellt hat, ist, die Wandtemperatur kontinuierlich zu schätzen - und zwar in Abhängigkeit von Innen- und Außentemperatur. Hierzu ist es nötig, eine kleine Messreihe mit einem Infrarotthermometer zu machen: Gemessen wird hiermit die Oberflächentemperatur der Wand an der kältesten Stelle, die sich im Raum finden lässt - also z.B. in der Fensterzarge. Zusätzlich benötigen wir die Innentemperatur des Raumes und die Außentemperatur, die FHEM zu dieser Zeit gemessen hat - die kann man ja nach der Messung im FileLog / [[DbLog]] nachschauen.&lt;br /&gt;
&lt;br /&gt;
Aus diesen 3 Werten berechnen wir uns einen &amp;quot;Isolationsfaktor&amp;quot; K:&lt;br /&gt;
&lt;br /&gt;
 K = (Oberflächentemperatur - Außentemperatur) / (Innentemperatur - Außentemperatur)&lt;br /&gt;
&lt;br /&gt;
Wichtig ist es, die Messung durchzuführen, wenn es draußen richtig schön kalt ist (spät abends / nachts bei Minusgraden) und die Raumtemperatur längere Zeit konstant war - direkt nach dem Aufheizen des Bades bei 15 Grad Außentemperatur ergibt das Ganze also eher keine genauen Werte. Die Außentemperatur sollte idealerweise auch konstant sein, aber das ist sie nunmal nicht, daher kann das Ganze nicht perfekt funktionieren - aber für unsere Zwecke durchaus ausreichend. Die Messung solltet ihr aber auf jeden Fall ein paar mal wiederholen (6-7 mal zu verschiedenen Zeiten, am besten an mehreren Tagen),  ggf. Ausreißer aussortieren und dann K mitteln. Sollte K bei euch nicht sonderlich konstant sein - was je nach Bausubstanz / Beheizung durchaus möglich ist - nehmt tendentiell eher einen kleineren Wert, geht also von schlechterer Dämmung aus, wenn ihr sicher sein wollt, dass es nicht schimmelt. Bei mir ergaben sich für meine Altbauwohnung Werte zwischen 0,67 und 0,70 - Mittelwert ist 0,68, den verwende ich seitdem. &lt;br /&gt;
&lt;br /&gt;
Über den Wert können wir nun mit folgender Funktion für die 99_myUtils.pm künftig die Wandtemperatur jederzeit aus Innen- und Außentemperatur schätzen:&lt;br /&gt;
&lt;br /&gt;
 sub wallSurfaceTemp($$$)&lt;br /&gt;
 # Estimates the temperature of the inner wall surface given the outside Temperature in degrees of C as $Tinside,&lt;br /&gt;
 # the outdoor-temperature $Toutside in degrees of C and an insulation Factor $Kinsulation with K = 1 (theoretical perfect insulation, e.g. vacuum) and&lt;br /&gt;
 # K = 0 (no insulation at all, means: less than a sheet of paper). You have to calculate K on your own by measuring inside-, outside-, and wall-temperature,&lt;br /&gt;
 # preferably by averaging multiple measurements on cold days with constant heating of the room. &lt;br /&gt;
 {&lt;br /&gt;
   my ($Tinside, $Toutside, $Kinsulation) = @_;&lt;br /&gt;
   my $Tsurface =  ($Tinside * $Kinsulation) + ($Toutside * (1 - $Kinsulation));&lt;br /&gt;
   return $Tsurface;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wirklich genau ist die Methode wie gesagt nicht und unterliegt gewissen Schwankungen. Sie ist inspiriert durch [http://www.u-wert.net/u-wert-messen/ diesen Artikel] (und auf das für uns nötigste weiter vereinfacht). Dort sind auch die prinzipiellen Nachteile dieser Schätzung diskutiert worden. Ich habe meine Messreihe vor knapp einem Jahr durchgeführt und immer mal wieder das Ergebnis  mit der realen Wandtemperatur verglichen: die Abweichung lag maximal bei 1,5 Grad, normalerweise stimmte sie aber auf +/- 0,5 Grad genau. Damit kann ich gut leben ;-) Möglicherweise funktioniert das bei euch nicht so gut - einfach testen.&lt;br /&gt;
&lt;br /&gt;
==Alles zusammenpacken==&lt;br /&gt;
Die zwei neuen Werte (Wandtemperatur und „Wandfeuchte“ - bessergesagt, relative Luftfeuchte in Wandnähe) können wir nun z.B. in die UserReadings unseres Wandthermostaten packen. Hier mal ein Beispiel zum kopieren in das Feld für das UserReadings-Attribut:&lt;br /&gt;
&lt;br /&gt;
 wandTemp { sprintf(&amp;quot;%.1f&amp;quot;, wallSurfaceTemp(ReadingsVal(&amp;quot;kuechenthermometer&amp;quot;,&amp;quot;temperature&amp;quot;,15),ReadingsVal(&amp;quot;aussenthermometer&amp;quot;,&amp;quot;temperature&amp;quot;,0),0.68)) }, \&lt;br /&gt;
    wandHumidity { sprintf(&amp;quot;%.1f&amp;quot;, shiftRelHumidity( ReadingsVal(&amp;quot;kuechenthermometer&amp;quot;,&amp;quot;temperature&amp;quot;,17), ReadingsVal(&amp;quot;kuechenthermometer&amp;quot;,&amp;quot;humidity&amp;quot;,90), \&lt;br /&gt;
    wallSurfaceTemp( ReadingsVal(&amp;quot;kuechenthermometer&amp;quot;,&amp;quot;temperature&amp;quot;,15), ReadingsVal(&amp;quot;aussenthermometer&amp;quot;,&amp;quot;temperature&amp;quot;,0), 0.68) ) ) }&lt;br /&gt;
&lt;br /&gt;
Nicht vergessen, die 0.68 durch euren ermittelten K-wert zu ersetzen und event-on-change-reading anzupassen falls gesetzt, so dass ihr auch Events für die Userreadings bekommt.&lt;br /&gt;
&lt;br /&gt;
Nun könnt ihr beide Werte ganz normal in Plots einfügen, euch Warnungen bei wandHumidity &amp;gt; 70% oder 80% schicken lassen oder das ganze auch per DOIF zur Entfeuchterregelung benutzen:&lt;br /&gt;
&lt;br /&gt;
 define di_bad.oben.luftentfeuchter \&lt;br /&gt;
    DOIF ([bad.oben.thermometer:wandHumidity] &amp;gt; 68 and [bad.oben.fenster] eq &amp;quot;geschlossen&amp;quot;) (set bad.oben.luftentfeuchter_Sw on) \&lt;br /&gt;
    DOELSEIF ([bad.oben.thermometer:wandHumidity] &amp;lt; 60) (set bad.oben.luftentfeuchter_Sw off) \&lt;br /&gt;
    DOELSEIF ([bad.oben.fenster] eq &amp;quot;offen&amp;quot;) (set bad.oben.luftentfeuchter_Sw off)&lt;br /&gt;
&lt;br /&gt;
Hier regele ich einen Luftentfeuchter an einem [[HM-ES-PMSw1-Pl Funk-Schaltaktor 1-fach mit Leistungsmessung|HomeMatic Zwischenstecker mit Leistungsmessung]] genau so, dass die Wand immer unter 70% bleibt (mit 2% Sicherheitsmarge). Und beim Lüften geht das Ding sofort aus. Ihr müsst dann nur noch einen Luftentfeuchter finden, der diese Art des Ein-/Ausschaltens per Steckerziehen mitmacht und ein wenig mit der Hysterese (dem Abschaltpunkt - hier 60%) spielen, so dass es in euren Raum passt. Ich verwende übrigens einen comfee MDF2-16DEN3 - ein sehr preiswerter Luftentfeuchter, der nicht wie viele andere die Eigenart hat, nach Stromwiederkehr einfach auszubleiben. Er genehmigt seinem Kompressor danach zwar eine kurze Zwangspause, läuft dann aber wieder an.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* {{Link2Forum|Topic=29773|LinkText=Forenthread zu diesem Thema}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HOWTOS]]&lt;/div&gt;</summary>
		<author><name>ChristophMorrison</name></author>
	</entry>
</feed>