<?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=C2j2</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=C2j2"/>
	<link rel="alternate" type="text/html" href="http://wiki.fhem.de/wiki/Spezial:Beitr%C3%A4ge/C2j2"/>
	<updated>2026-04-10T22:56:28Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=28830</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=28830"/>
		<updated>2018-12-30T15:52:38Z</updated>

		<summary type="html">&lt;p&gt;C2j2: Reihenfolge logischer ;)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; (ZE0 und ZE1) in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird - wie empfohlen - das Auto beispielsweise bis maximal 80% geladen, um den Akku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ganze sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ladesteuerung an der PV-Anlage.png|noframe|Ladesteuerung an der PV-Anlage]]&lt;br /&gt;
&lt;br /&gt;
wobei die Abschaltlogik hier im Bild noch nicht implementiert ist, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird - und da fehlt dann nur noch das Abschalten.&lt;br /&gt;
&lt;br /&gt;
== Vorgehensweise ==&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte des &#039;&#039;&#039;Leaf&#039;&#039;&#039; heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die Smartphone-App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Abfrage über eine Web-URL (&#039;&#039;&#039;CARWINGS-API&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Alternative &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine Smartphone-App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben. Und das in kurzen Intervallen, wenn man möchte.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
==== Die Arbeit ====&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
=== Alternative &#039;&#039;&#039;CARWINGS&#039;&#039;&#039; API ===&lt;br /&gt;
&lt;br /&gt;
Diese API (Zugriff über einen Internet-Request auf eine feste Seite des Betreibers mit zum Auto passenden Zugangsdaten) ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* nicht abhängig vom Akku eines Smartphones (dessen Verbrauch kann aber optimiert werden mit Tasker, AutomateIt und ähnlichen Apps)&lt;br /&gt;
* man kann auch die Klimatisierung ein- und ausstellen&lt;br /&gt;
* und den Ort des Autos abfragen.&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* langsames Update: eine SOC-Abfrage braucht knapp 2 Minuten (was aber egal ist, da das eh periodisch durchgeführt wird)&lt;br /&gt;
&lt;br /&gt;
Dazu habe ich mittlerweile ein Modul für FHEM gebaut, dass das alles in FHEM einbindbar ist: [https://forum.fhem.de/index.php/topic,92163.0.html].&lt;br /&gt;
Mittlerweile setze ich voll auf dieses Modul.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der dazu passende &#039;&#039;&#039;Leaf&#039;&#039;&#039;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Examples]]&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=28829</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=28829"/>
		<updated>2018-12-30T15:51:25Z</updated>

		<summary type="html">&lt;p&gt;C2j2: Hinweis auf mein neues Modul eingebaut, und die Pro-Contra-Liste anhand der neuen Erkenntnisse korrigiert.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; (ZE0 und ZE1) in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird - wie empfohlen - das Auto beispielsweise bis maximal 80% geladen, um den Akku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ganze sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ladesteuerung an der PV-Anlage.png|noframe|Ladesteuerung an der PV-Anlage]]&lt;br /&gt;
&lt;br /&gt;
wobei die Abschaltlogik hier im Bild noch nicht implementiert ist, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird - und da fehlt dann nur noch das Abschalten.&lt;br /&gt;
&lt;br /&gt;
== Vorgehensweise ==&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte des &#039;&#039;&#039;Leaf&#039;&#039;&#039; heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die Smartphone-App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Abfrage über eine Web-URL (&#039;&#039;&#039;CARWINGS-API&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Alternative &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine Smartphone-App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben. Und das in kurzen Intervallen, wenn man möchte.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
==== Die Arbeit ====&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
=== Alternative &#039;&#039;&#039;CARWINGS&#039;&#039;&#039; API ===&lt;br /&gt;
&lt;br /&gt;
Diese API (Zugriff über einen Internet-Request auf eine feste Seite des Betreibers mit zum Auto passenden Zugangsdaten) ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Mittlerweile setze ich voll auf dieses Modul.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* nicht abhängig vom Akku eines Smartphones (dessen Verbrauch kann aber optimiert werden mit Tasker, AutomateIt und ähnlichen Apps)&lt;br /&gt;
* man kann auch die Klimatisierung ein- und ausstellen&lt;br /&gt;
* und den Ort des Autos abfragen.&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* langsames Update: eine SOC-Abfrage braucht knapp 2 Minuten (was aber egal ist, da das eh periodisch durchgeführt wird)&lt;br /&gt;
&lt;br /&gt;
Dazu habe ich mittlerweile ein Modul für FHEM gebaut, dass das alles in FHEM einbindbar ist: https://forum.fhem.de/index.php/topic,92163.0.html.&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der dazu passende &#039;&#039;&#039;Leaf&#039;&#039;&#039;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Examples]]&lt;br /&gt;
[[Kategorie:Code Snippets]]&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27941</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27941"/>
		<updated>2018-09-26T16:19:10Z</updated>

		<summary type="html">&lt;p&gt;C2j2: Bereitstellung interner Daten des Elektroautos Nissan Leaf in FHEM&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; (ZE0 und ZE1) in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird - wie empfohlen - das Auto beispielsweise bis maximal 80% geladen, um den Akku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ganze sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ladesteuerung an der PV-Anlage.png|noframe|Ladesteuerung an der PV-Anlage]]&lt;br /&gt;
&lt;br /&gt;
wobei die Abschaltlogik hier im Bild noch nicht implementiert ist, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird - und da fehlt dann nur noch das Abschalten.&lt;br /&gt;
&lt;br /&gt;
== Vorgehensweise ==&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte des &#039;&#039;&#039;Leaf&#039;&#039;&#039; heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die Smartphone-App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Abfrage über eine Web-URL (&#039;&#039;&#039;CARWINGS-API&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Alternative &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine Smartphone-App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben. Und das in kurzen Intervallen, wenn man möchte.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
==== Die Arbeit ====&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
=== Alternative &#039;&#039;&#039;CARWINGS&#039;&#039;&#039; API ===&lt;br /&gt;
&lt;br /&gt;
Diese API (Zugriff über einen Internet-Request auf eine feste Seite des Betreibers mit zum Auto passenden Zugangsdaten) ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* nicht abhängig vom Akku eines Smartphones (dessen Verbrauch kann aber optimiert werden mit Tasker und ähnlichen Apps)&lt;br /&gt;
* man kann auch die Klimatisierung ein- und ausstellen&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* nicht lokal im WLAN (benötigt Internet)&lt;br /&gt;
* langsames Update: angeblich maximal alle 20 Minuten, da die Abfrage über GSM geht. Dadurch auch anhängig vom Handynetz in der Garage.&lt;br /&gt;
* das GSM-Modul im Leaf belastet den Autoakku (nicht den Fahrakku!)&lt;br /&gt;
&lt;br /&gt;
Hierfür muss man also einen kleinen Server bauen, der periodisch den Zustand abfragt und den bekannten&amp;quot;Leaf&amp;quot;-Dumnmy beziehungsweise dessen Readings setzt.&lt;br /&gt;
&lt;br /&gt;
* [https://community.openenergymonitor.org/t/nissan-leaf-ev-status-control-via-mqtt/2672 Github: CARWINGS-MQTT-Schnittstelle]&lt;br /&gt;
* [https://github.com/snaptec/openWB/tree/master/modules/soc_leaf Github: Leaf-Modul in OpenWB]&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der dazu passende &#039;&#039;&#039;Leaf&#039;&#039;&#039;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27940</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27940"/>
		<updated>2018-09-25T21:05:49Z</updated>

		<summary type="html">&lt;p&gt;C2j2: /* Alternative Leaf Spy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos, hier &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird das Auto beispielsweise bis maximal 80% geladen, um den Aku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ganze sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ladesteuerung an der PV-Anlage.png|noframe|Ladesteuerung an der PV-Anlage]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
wobei hier die Abschaltlogik noch nicht implementiert ist für dieses Bild, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird.&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Web-URL (CARWINGS-API)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Leaf Spy ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben. Und das in kurzen Intervallen, wenn man möchte.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
=== Die Arbeit ===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
== Alternative CARWINGS API ==&lt;br /&gt;
&lt;br /&gt;
Diese API ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* nicht abhängig vom Akku eines Smartphones (dessen Verbrauch kann aber optimiert werden mit Tasker und ähnlichen Apps)&lt;br /&gt;
* man kann auch die Klimatisierung ein- und ausstellen&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* nicht lokal im WLAN (benötigt Internet)&lt;br /&gt;
* langsames Update: angeblich maximal alle 20 Minuten, da die Abfrage über GSM geht. Dadurch auch anhängig vom Handynetz in der Garage.&lt;br /&gt;
* das GSM-Modul im Leaf belastet den Autoakku (nicht den Fahrakku!)&lt;br /&gt;
&lt;br /&gt;
Hierfür muss man also einen kleinen Server bauen, der periodisch den Zustand abfragt und den bekannten&amp;quot;Leaf&amp;quot;-Dumnmy beziehungsweise dessen Readings setzt.&lt;br /&gt;
&lt;br /&gt;
* [https://community.openenergymonitor.org/t/nissan-leaf-ev-status-control-via-mqtt/2672 Github: CARWINGS-MQTT-Schnittstelle]&lt;br /&gt;
* [https://github.com/snaptec/openWB/tree/master/modules/soc_leaf Github: Leaf-Modul in OpenWB]&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der &amp;quot;Leaf&amp;quot;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27939</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27939"/>
		<updated>2018-09-25T21:05:04Z</updated>

		<summary type="html">&lt;p&gt;C2j2: /* Alternative CARWINGS API */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos, hier &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird das Auto beispielsweise bis maximal 80% geladen, um den Aku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ganze sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ladesteuerung an der PV-Anlage.png|noframe|Ladesteuerung an der PV-Anlage]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
wobei hier die Abschaltlogik noch nicht implementiert ist für dieses Bild, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird.&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Web-URL (CARWINGS-API)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Leaf Spy ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
=== Die Arbeit ===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
== Alternative CARWINGS API ==&lt;br /&gt;
&lt;br /&gt;
Diese API ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* nicht abhängig vom Akku eines Smartphones (dessen Verbrauch kann aber optimiert werden mit Tasker und ähnlichen Apps)&lt;br /&gt;
* man kann auch die Klimatisierung ein- und ausstellen&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* nicht lokal im WLAN (benötigt Internet)&lt;br /&gt;
* langsames Update: angeblich maximal alle 20 Minuten, da die Abfrage über GSM geht. Dadurch auch anhängig vom Handynetz in der Garage.&lt;br /&gt;
* das GSM-Modul im Leaf belastet den Autoakku (nicht den Fahrakku!)&lt;br /&gt;
&lt;br /&gt;
Hierfür muss man also einen kleinen Server bauen, der periodisch den Zustand abfragt und den bekannten&amp;quot;Leaf&amp;quot;-Dumnmy beziehungsweise dessen Readings setzt.&lt;br /&gt;
&lt;br /&gt;
* [https://community.openenergymonitor.org/t/nissan-leaf-ev-status-control-via-mqtt/2672 Github: CARWINGS-MQTT-Schnittstelle]&lt;br /&gt;
* [https://github.com/snaptec/openWB/tree/master/modules/soc_leaf Github: Leaf-Modul in OpenWB]&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der &amp;quot;Leaf&amp;quot;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27938</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27938"/>
		<updated>2018-09-25T21:04:47Z</updated>

		<summary type="html">&lt;p&gt;C2j2: /* Alternative CARWINGS API */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos, hier &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird das Auto beispielsweise bis maximal 80% geladen, um den Aku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ganze sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ladesteuerung an der PV-Anlage.png|noframe|Ladesteuerung an der PV-Anlage]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
wobei hier die Abschaltlogik noch nicht implementiert ist für dieses Bild, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird.&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Web-URL (CARWINGS-API)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Leaf Spy ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
=== Die Arbeit ===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
== Alternative CARWINGS API ==&lt;br /&gt;
&lt;br /&gt;
Diese API ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* nicht abhängig vom Akku eines Smartphones (dessen Verbrauch kann aber optimiert werden mit Tasker und ähnlichen Apps)&lt;br /&gt;
* man kann auch die Klimatisierung ein- und ausstellen&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* nicht lokal im WLAN (benötigt Internet)&lt;br /&gt;
* langsames Update: angeblich maximal alle 20 Minuten, da die Abfrage über GSM geht. Dadurch auch anhängig vom Handynetz in der Garage.&lt;br /&gt;
* das GSM-Modul im Leaf belastet den Autoakku (nicht den Fahrakku!)&lt;br /&gt;
&lt;br /&gt;
Hierfür muss man also einen kleinen Server bauen, der periodisch den Zustand abfragt und den bekannten&amp;quot;Leaf&amp;quot;-Dumnmy bwziehungsweise dessen Readings setzt.&lt;br /&gt;
&lt;br /&gt;
* [https://community.openenergymonitor.org/t/nissan-leaf-ev-status-control-via-mqtt/2672 Github: CARWINGS-MQTT-Schnittstelle]&lt;br /&gt;
* [https://github.com/snaptec/openWB/tree/master/modules/soc_leaf Github: Leaf-Modul in OpenWB]&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der &amp;quot;Leaf&amp;quot;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27935</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27935"/>
		<updated>2018-09-25T20:50:03Z</updated>

		<summary type="html">&lt;p&gt;C2j2: Bild prominenter eingebaut&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos, hier &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird das Auto beispielsweise bis maximal 80% geladen, um den Aku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ganze sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ladesteuerung an der PV-Anlage.png|noframe|Ladesteuerung an der PV-Anlage]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
wobei hier die Abschaltlogik noch nicht implementiert ist für dieses Bild, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird.&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Web-URL (CARWINGS-API)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Leaf Spy ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
=== Die Arbeit ===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
== Alternative CARWINGS API ==&lt;br /&gt;
&lt;br /&gt;
Diese API ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Nachteil ist für mich, dass man diese API anscheinend nicht so häufig aufrufen darf oder kann, maximal etwa alle 20 Minuten, eine Abfrage aktiviert das GSM-Modul des Leaf und wartet die Antwort ab. Das reicht allerdings gut für die Ladung zuhause. Um das auszunutzen man einen kleinen Web-Client laufen lassen, der die API benutzt und die Werte ebenso an unseren &amp;quot;Leaf&amp;quot;-Dummy übergibt. Hat jemand Lust? ;)&lt;br /&gt;
&lt;br /&gt;
* [https://community.openenergymonitor.org/t/nissan-leaf-ev-status-control-via-mqtt/2672 Github: CARWINGS-MQTT-Schnittstelle]&lt;br /&gt;
* [https://github.com/snaptec/openWB/tree/master/modules/soc_leaf Github: Leaf-Modul in OpenWB]&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der &amp;quot;Leaf&amp;quot;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27934</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27934"/>
		<updated>2018-09-25T20:48:43Z</updated>

		<summary type="html">&lt;p&gt;C2j2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos, hier &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird das Auto beispielsweise bis maximal 80% geladen, um den Aku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ganze sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ladesteuerung an der PV-Anlage.png|mini|Ladesteuerung an der PV-Anlage]]&lt;br /&gt;
&lt;br /&gt;
wobei hier die Abschaltlogik noch nicht implementiert ist für dieses Bild, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird.&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Web-URL (CARWINGS-API)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Leaf Spy ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
=== Die Arbeit ===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
== Alternative CARWINGS API ==&lt;br /&gt;
&lt;br /&gt;
Diese API ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Nachteil ist für mich, dass man diese API anscheinend nicht so häufig aufrufen darf oder kann, maximal etwa alle 20 Minuten, eine Abfrage aktiviert das GSM-Modul des Leaf und wartet die Antwort ab. Das reicht allerdings gut für die Ladung zuhause. Um das auszunutzen man einen kleinen Web-Client laufen lassen, der die API benutzt und die Werte ebenso an unseren &amp;quot;Leaf&amp;quot;-Dummy übergibt. Hat jemand Lust? ;)&lt;br /&gt;
&lt;br /&gt;
* [https://community.openenergymonitor.org/t/nissan-leaf-ev-status-control-via-mqtt/2672 Github: CARWINGS-MQTT-Schnittstelle]&lt;br /&gt;
* [https://github.com/snaptec/openWB/tree/master/modules/soc_leaf Github: Leaf-Modul in OpenWB]&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der &amp;quot;Leaf&amp;quot;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Datei:Ladesteuerung_an_der_PV-Anlage.png&amp;diff=27933</id>
		<title>Datei:Ladesteuerung an der PV-Anlage.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Datei:Ladesteuerung_an_der_PV-Anlage.png&amp;diff=27933"/>
		<updated>2018-09-25T20:48:23Z</updated>

		<summary type="html">&lt;p&gt;C2j2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist die SOC-Begrenzun einzubauen...&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27932</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27932"/>
		<updated>2018-09-25T20:41:12Z</updated>

		<summary type="html">&lt;p&gt;C2j2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos, hier &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird das Auto beispielsweise bis maximal 80% geladen, um den Aku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Web-URL (CARWINGS-API)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Leaf Spy ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
=== Die Arbeit ===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
== Alternative CARWINGS API ==&lt;br /&gt;
&lt;br /&gt;
Diese API ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Nachteil ist für mich, dass man diese API anscheinend nicht so häufig aufrufen darf oder kann, maximal etwa alle 20 Minuten, eine Abfrage aktiviert das GSM-Modul des Leaf und wartet die Antwort ab. Das reicht allerdings gut für die Ladung zuhause. Um das auszunutzen man einen kleinen Web-Client laufen lassen, der die API benutzt und die Werte ebenso an unseren &amp;quot;Leaf&amp;quot;-Dummy übergibt. Hat jemand Lust? ;)&lt;br /&gt;
&lt;br /&gt;
* [https://community.openenergymonitor.org/t/nissan-leaf-ev-status-control-via-mqtt/2672 Github: CARWINGS-MQTT-Schnittstelle]&lt;br /&gt;
* [https://github.com/snaptec/openWB/tree/master/modules/soc_leaf Github: Leaf-Modul in OpenWB]&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der &amp;quot;Leaf&amp;quot;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=LeafSpy&amp;diff=27931</id>
		<title>LeafSpy</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=LeafSpy&amp;diff=27931"/>
		<updated>2018-09-25T20:39:28Z</updated>

		<summary type="html">&lt;p&gt;C2j2: C2j2 verschob die Seite LeafSpy nach Ladezustand des Nissan Leaf nutzbar machen: Die CARWINGS-API kam noch dazu, so dass es nicht nur eine Seite für Leaf Spy ist&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#WEITERLEITUNG [[Ladezustand des Nissan Leaf nutzbar machen]]&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27930</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27930"/>
		<updated>2018-09-25T20:39:28Z</updated>

		<summary type="html">&lt;p&gt;C2j2: C2j2 verschob die Seite LeafSpy nach Ladezustand des Nissan Leaf nutzbar machen: Die CARWINGS-API kam noch dazu, so dass es nicht nur eine Seite für Leaf Spy ist&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Todo|Bitte noch ergänzen, wie z.B. die Einbindung in FHEM funktioniert und was die Einbindung hier genau bedeutet - vielleicht mit einem Screenshot?}}&lt;br /&gt;
&lt;br /&gt;
== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos, hier &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird das Auto beispielsweise bis maximal 80% geladen, um den Aku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Web-URL (CARWINGS-API)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Leaf Spy ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
=== Die Arbeit ===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
== Alternative CARWINGS API ==&lt;br /&gt;
&lt;br /&gt;
Diese API ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Nachteil ist für mich, dass man diese API anscheinend nicht so häufig aufrufen darf oder kann, maximal etwa alle 20 Minuten, eine Abfrage aktiviert das GSM-Modul des Leaf und wartet die Antwort ab. Das reicht allerdings gut für die Ladung zuhause. Um das auszunutzen man einen kleinen Web-Client laufen lassen, der die API benutzt und die Werte ebenso an unseren &amp;quot;Leaf&amp;quot;-Dummy übergibt. Hat jemand Lust? ;)&lt;br /&gt;
&lt;br /&gt;
* [https://community.openenergymonitor.org/t/nissan-leaf-ev-status-control-via-mqtt/2672 Github: CARWINGS-MQTT-Schnittstelle]&lt;br /&gt;
* [https://github.com/snaptec/openWB/tree/master/modules/soc_leaf Github: Leaf-Modul in OpenWB]&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der &amp;quot;Leaf&amp;quot;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27929</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27929"/>
		<updated>2018-09-25T20:38:17Z</updated>

		<summary type="html">&lt;p&gt;C2j2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Todo|Bitte noch ergänzen, wie z.B. die Einbindung in FHEM funktioniert und was die Einbindung hier genau bedeutet - vielleicht mit einem Screenshot?}}&lt;br /&gt;
&lt;br /&gt;
== Idee: Ladezustand des Leaf in FHEM nutzbar zu machen ==&lt;br /&gt;
&lt;br /&gt;
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos, hier &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039; in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird das Auto beispielsweise bis maximal 80% geladen, um den Aku nicht durch Volladung stärker als nötig zu belasten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=perl&amp;gt;&lt;br /&gt;
 my $leafBatSOC = ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0);&lt;br /&gt;
 my $leafBatSOCMax = ReadingsNum(&amp;quot;MaxSOC&amp;quot;, &amp;quot;state&amp;quot;, 100);&lt;br /&gt;
 &lt;br /&gt;
 if ($leafBatSOC &amp;lt; $leafBatSOCMax)&lt;br /&gt;
  {&lt;br /&gt;
  // charge&lt;br /&gt;
  }&lt;br /&gt;
 else&lt;br /&gt;
  {&lt;br /&gt;
  // do not charge&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten, an die internen Werte heranzukommen:&lt;br /&gt;
&lt;br /&gt;
# über die App &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039;&lt;br /&gt;
# über eine Web-URL (CARWINGS-API)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Leaf Spy ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist &amp;quot;Flask&amp;quot;, der die REST-URL im Handumdrehen auseinandernimmt.&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
=== Die Arbeit ===&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), kann man z.B. in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot; unterbringen&lt;br /&gt;
&lt;br /&gt;
* und eine Dummy-Variable &amp;quot;Leaf&amp;quot; FHEM einrichten mit diversen Readings (&amp;quot;BatterySOC&amp;quot; etc), die durch das Python-Script gesetzt werden. Siehe auch unten.&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM im korrespondierende Dummy &amp;quot;Leaf&amp;quot; das Reading &amp;quot;BatterySOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem Boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen (Google...)&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
== Alternative CARWINGS API ==&lt;br /&gt;
&lt;br /&gt;
Diese API ist die &amp;quot;offizielle&amp;quot; Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.&lt;br /&gt;
&lt;br /&gt;
Nachteil ist für mich, dass man diese API anscheinend nicht so häufig aufrufen darf oder kann, maximal etwa alle 20 Minuten, eine Abfrage aktiviert das GSM-Modul des Leaf und wartet die Antwort ab. Das reicht allerdings gut für die Ladung zuhause. Um das auszunutzen man einen kleinen Web-Client laufen lassen, der die API benutzt und die Werte ebenso an unseren &amp;quot;Leaf&amp;quot;-Dummy übergibt. Hat jemand Lust? ;)&lt;br /&gt;
&lt;br /&gt;
* [https://community.openenergymonitor.org/t/nissan-leaf-ev-status-control-via-mqtt/2672 Github: CARWINGS-MQTT-Schnittstelle]&lt;br /&gt;
* [https://github.com/snaptec/openWB/tree/master/modules/soc_leaf Github: Leaf-Modul in OpenWB]&lt;br /&gt;
&lt;br /&gt;
== Anhänge ==&lt;br /&gt;
&lt;br /&gt;
==== Das Server-Skript für Leaf Spy ====&lt;br /&gt;
Das Skript, das (auf dem &#039;&#039;Raspberry Pi&#039;&#039; mit dem Aufruf &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=py&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	# Annahme: läuft auf dem gleichen RASPI wie FHEM&lt;br /&gt;
	# Annahme: WEBapi benutzt Port 8088&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatterySOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryCapacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryTemp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;BatteryGids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;AmbientTemp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;SmartphoneSOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== und der &amp;quot;Leaf&amp;quot;-Dummy ====&lt;br /&gt;
&lt;br /&gt;
 Internals: &lt;br /&gt;
   CFGFN &lt;br /&gt;
   NAME       Leaf &lt;br /&gt;
   NR         3481 &lt;br /&gt;
   STATE      SOC=79% Gids=88, Temp=50°C &lt;br /&gt;
   TYPE       dummy &lt;br /&gt;
 Attributes: &lt;br /&gt;
   readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC &lt;br /&gt;
   room       Auto &lt;br /&gt;
   stateFormat { sprintf(&amp;quot;SOC=%d%% Gids=%d, Temp=%d°C&amp;quot;, ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatterySOC&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;BatteryGids&amp;quot;, 0), ReadingsNum(&amp;quot;Leaf&amp;quot;, &amp;quot;AmbientTemp&amp;quot;, 0)); }&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27920</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27920"/>
		<updated>2018-09-24T16:02:39Z</updated>

		<summary type="html">&lt;p&gt;C2j2: /* Dann die Arbeit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware für das Laden haben. Bei mir ist das - oh Wunder - FHEM.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Ich habe dazu &amp;quot;Flask&amp;quot; als Mini-Server genommen. Also:&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte). Hier bei mir ist das noch etwas komplexer, über ein QNAP-NAS mit Apache und einem redirect, so dass &amp;quot;https://meinname.myqnapcloud.com/leaf&amp;quot; intern ungeleitet wird auf &amp;quot;http://raspberrypi:5000/app&amp;quot; und somit auf mein Proxy-Skript. Die Einrichtung, auf diese Weise SSL-Zugriff auf FHEM zu haben und nun auch auf das Skript, kostete viele Stunden, macht im Nachhinein aber reich und schön. ;)&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
==== Dann die Arbeit ====&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), bei mir in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* und die paar Dummy-Variablen in FHEM einrichten (&amp;lt;code&amp;gt;LEAF_Battery_...&amp;lt;/code&amp;gt; und so, siehe Skript)&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM das korrespondierende Dummy &amp;quot;Leaf_Battery_SOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen. &lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
==== Das Skript, das über &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird: ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=set%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Battery_SOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Battery_Capacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Battery_Temp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Battery_Gids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Ambient_Temp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Device_SOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27919</id>
		<title>Ladezustand des Nissan Leaf nutzbar machen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Ladezustand_des_Nissan_Leaf_nutzbar_machen&amp;diff=27919"/>
		<updated>2018-09-24T16:00:49Z</updated>

		<summary type="html">&lt;p&gt;C2j2: Daten der &amp;quot;LeafSpy&amp;quot;-App in FHEM nutzbar zu machen, um die Nissan Leaf-Informationen in FHEM nutzen zu können&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; ist eine App für das Elektroauto &#039;&#039;&#039;Nissan Leaf&#039;&#039;&#039;, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:&lt;br /&gt;
&lt;br /&gt;
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und&lt;br /&gt;
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben.&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise des SOC (&amp;quot;State of Charge&amp;quot;)-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware für das Laden haben. Bei mir ist das - oh Wunder - FHEM.&lt;br /&gt;
&lt;br /&gt;
Also braucht man einen kleinen Server, der die HTTP-Daten vom &#039;&#039;&#039;Leaf Spy&#039;&#039;&#039; empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.&lt;br /&gt;
&lt;br /&gt;
Was liegt näher, als diesen Server auf dem &#039;&#039;Raspberry Pi&#039;&#039; einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Ich habe dazu &amp;quot;Flask&amp;quot; als Mini-Server genommen. Also:&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen: ====&lt;br /&gt;
&lt;br /&gt;
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte). Hier bei mir ist das noch etwas komplexer, über ein QNAP-NAS mit Apache und einem redirect, so dass &amp;quot;https://meinname.myqnapcloud.com/leaf&amp;quot; intern ungeleitet wird auf &amp;quot;http://raspberrypi:5000/app&amp;quot; und somit auf mein Proxy-Skript. Die Einrichtung, auf diese Weise SSL-Zugriff auf FHEM zu haben und nun auch auf das Skript, kostete viele Stunden, macht im Nachhinein aber reich und schön. ;)&lt;br /&gt;
&lt;br /&gt;
* LeafSpy installiert und funktionsfähig&lt;br /&gt;
&lt;br /&gt;
==== Dann die Arbeit ====&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Flask&amp;quot; installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung &amp;quot;venv&amp;quot; einrichten - findet man aber alles irgendwie: Stichwörter sind also &amp;quot;Flask&amp;quot; und &amp;quot;venv&amp;quot;). Das ist der Hauptschritt.&lt;br /&gt;
&lt;br /&gt;
* ein kleines Python-Skript als &amp;quot;Proxy&amp;quot; einrichten (siehe unten), bei mir in &amp;quot;/home/pi/leaf-fhem-bridge/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* und die paar Dummy-Variablen in FHEM einrichten (&amp;lt;code&amp;gt;LEAF_Battery_...&amp;lt;/code&amp;gt; und so, siehe Skript)&lt;br /&gt;
&lt;br /&gt;
* in FHEM die &amp;lt;code&amp;gt;WEBapi&amp;lt;/code&amp;gt; einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff&lt;br /&gt;
&lt;br /&gt;
* wenn alles klappt, diesen Flask-Server bei jedem boot des &#039;&#039;Raspiberry Pi&#039;&#039; starten lassen. Testen mit &amp;quot;http://raspberrypi:5000/app?SOC=80&amp;quot;, dann müßte im FHEM das korrespondierende Dummy &amp;quot;Leaf_Battery_SOC&amp;quot; auf 80 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* von außen testen über &amp;quot;https://meine-IP/leaf?SOC=80&amp;quot; - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...&lt;br /&gt;
&lt;br /&gt;
Bei mir ist das alles derzeit noch &amp;quot;Trockenübung&amp;quot;, da mein Auto noch nicht hier in der Garage steht. Ich hoffe dass das &amp;lt;code&amp;gt;return &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.&lt;br /&gt;
&lt;br /&gt;
==== Das Skript, das über &amp;quot;phython &amp;lt;skriptname&amp;gt;.py&amp;quot; gestartet wird: ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
import urllib&lt;br /&gt;
import urllib2&lt;br /&gt;
from flask import Flask&lt;br /&gt;
from flask import request&lt;br /&gt;
&lt;br /&gt;
app = Flask(__name__)&lt;br /&gt;
&lt;br /&gt;
def post_fhem(key, value):&lt;br /&gt;
	url = &amp;quot;http://127.0.0.1:8088/fhem?cmd=set%20&amp;quot; + key + &amp;quot;%20&amp;quot; + value + &amp;quot;&amp;amp;XHR=1&amp;quot;&lt;br /&gt;
	req = urllib2.Request(url)&lt;br /&gt;
	response = urllib2.urlopen(req)&lt;br /&gt;
	page = response.read()&lt;br /&gt;
	return page&lt;br /&gt;
	&lt;br /&gt;
@app.route(&#039;/app&#039;, methods = [&#039;GET&#039;, &#039;POST&#039;])&lt;br /&gt;
def api_echo():&lt;br /&gt;
    if &#039;SOC&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Battery_SOC&#039;, request.args[&#039;SOC&#039;])&lt;br /&gt;
    if &#039;Ahr&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Battery_Capacity&#039;, request.args[&#039;Ahr&#039;])&lt;br /&gt;
    if &#039;BatTemp&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Battery_Temp&#039;, request.args[&#039;BatTemp&#039;])&lt;br /&gt;
    if &#039;Gids&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Battery_Gids&#039;, request.args[&#039;Gids&#039;])&lt;br /&gt;
    if &#039;Amb&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Ambient_Temp&#039;, request.args[&#039;Amb&#039;])&lt;br /&gt;
    if &#039;DevBat&#039; in request.args:&lt;br /&gt;
        post_fhem(&#039;Leaf_Device_SOC&#039;, request.args[&#039;DevBat&#039;])&lt;br /&gt;
    return &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    app.run(debug=True, host=&#039;0.0.0.0&#039;, port=5000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Sonnenspeicher&amp;diff=27869</id>
		<title>Sonnenspeicher</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Sonnenspeicher&amp;diff=27869"/>
		<updated>2018-09-15T10:53:34Z</updated>

		<summary type="html">&lt;p&gt;C2j2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hinweise zur Einbindung des Speichersystems von sonnen (https://sonnen.de/stromspeicher/) per HTTPMOD ==&lt;br /&gt;
&lt;br /&gt;
Im Kürze:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define sonnenbatterie HTTPMOD http://x.x.x.x:8080/api/v1/status 60&lt;br /&gt;
attr sonnenbatterie extractAllJSON 1&lt;br /&gt;
attr sonnenbatterie stateFormat {sprintf(&amp;quot;Verbrauch %d W: %d W aus PV + %d W %s Speicher + %d W %s Grid, SOC %d%%&amp;quot;, &lt;br /&gt;
ReadingsVal($name,&amp;quot;Consumption_W&amp;quot;,0),&lt;br /&gt;
ReadingsVal($name,&amp;quot;Production_W&amp;quot;,0),&lt;br /&gt;
abs(ReadingsVal($name,&amp;quot;Pac_total_W&amp;quot;,0)),&lt;br /&gt;
ReadingsVal($name,&amp;quot;FlowConsumptionBattery&amp;quot;,1) !=0 ? &amp;quot;aus&amp;quot; : &amp;quot;in&amp;quot;,&lt;br /&gt;
abs(ReadingsVal($name,&amp;quot;GridFeedIn_W&amp;quot;,0)),&lt;br /&gt;
ReadingsVal($name,&amp;quot;FlowConsumptionGrid&amp;quot;,1) !=0 ? &amp;quot;aus&amp;quot; : &amp;quot;in&amp;quot;,&lt;br /&gt;
ReadingsVal($name,&amp;quot;RSOC&amp;quot;,&amp;quot;-1&amp;quot;)&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Sonnenspeicher&amp;diff=27858</id>
		<title>Sonnenspeicher</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Sonnenspeicher&amp;diff=27858"/>
		<updated>2018-09-13T09:41:15Z</updated>

		<summary type="html">&lt;p&gt;C2j2: /* Hinweise zur schnellen Einbindung des Speichersystems von sonnen (https://sonnen.de/stromspeicher/) per HTTPMOD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hinweise zur Einbindung des Speichersystems von sonnen (https://sonnen.de/stromspeicher/) per HTTPMOD ==&lt;br /&gt;
&lt;br /&gt;
Im Kürze:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define sonnenbatterie HTTPMOD http://x.x.x.x:8080/api/v1/status 60&lt;br /&gt;
attr sonnenbatterie extractAllJSON 1&lt;br /&gt;
attr sonnenbatterie stateFormat {sprintf(&amp;quot;PV %d W -&amp;gt; Verbrauch %d W + %d W %s Speicher + %d W %s Grid, SOC %d%%&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;Production_W&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;Consumption_W&amp;quot;,0),\&lt;br /&gt;
abs(ReadingsVal($name,&amp;quot;Pac_total_W&amp;quot;,0)),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;flowProductionBattery&amp;quot;,0) &amp;gt; 0 ? &amp;quot;aus&amp;quot; : &amp;quot;in&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;GridFeedIn_W&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;flowConsumptionGrid&amp;quot;,0) &amp;gt; 0 ? &amp;quot;aus&amp;quot; : &amp;quot;in&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;RSOC&amp;quot;,&amp;quot;-1&amp;quot;)\&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Sonnenspeicher&amp;diff=27857</id>
		<title>Sonnenspeicher</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Sonnenspeicher&amp;diff=27857"/>
		<updated>2018-09-13T09:40:29Z</updated>

		<summary type="html">&lt;p&gt;C2j2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hinweise zur schnellen Einbindung des Speichersystems von sonnen (https://sonnen.de/stromspeicher/) per HTTPMOD ==&lt;br /&gt;
&lt;br /&gt;
Im Kürze:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define sonnenbatterie HTTPMOD http://x.x.x.x:8080/api/v1/status 60&lt;br /&gt;
attr sonnenbatterie extractAllJSON 1&lt;br /&gt;
attr sonnenbatterie stateFormat {sprintf(&amp;quot;PV %d W -&amp;gt; Verbrauch %d W + %d W %s Speicher + %d W %s Grid, SOC %d%%&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;Production_W&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;Consumption_W&amp;quot;,0),\&lt;br /&gt;
abs(ReadingsVal($name,&amp;quot;Pac_total_W&amp;quot;,0)),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;flowProductionBattery&amp;quot;,0) &amp;gt; 0 ? &amp;quot;aus&amp;quot; : &amp;quot;in&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;GridFeedIn_W&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;flowConsumptionGrid&amp;quot;,0) &amp;gt; 0 ? &amp;quot;aus&amp;quot; : &amp;quot;in&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;RSOC&amp;quot;,&amp;quot;-1&amp;quot;)\&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Leere_Seite_2&amp;diff=27841</id>
		<title>Leere Seite 2</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Leere_Seite_2&amp;diff=27841"/>
		<updated>2018-09-12T21:20:06Z</updated>

		<summary type="html">&lt;p&gt;C2j2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hinweise zur schnellen Einbindung von go-eCharger (https://go-e.co/de/) per HTTPMOD ==&lt;br /&gt;
&lt;br /&gt;
Voraussetzung ist, dass die HTTP-API aktiviert ist:&lt;br /&gt;
* Smartphone mit e-goCharger WLAN verbinden&lt;br /&gt;
* in &amp;quot;Cloud&amp;quot;, &amp;quot;erweiterte Einstellungen&amp;quot; das HTTP-Protokoll aktivieren&lt;br /&gt;
* &amp;quot;Neustart&amp;quot; auswählen (ohne diesen war bei mir die Box nicht zu erreichen)&lt;br /&gt;
* fertig, Smartphone kann wieder ins normale WLAN&lt;br /&gt;
&lt;br /&gt;
Dann in FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define go_eCharger HTTPMOD http://go-eCharger/status 30&lt;br /&gt;
attr go_eCharger extractAllJSON 1&lt;br /&gt;
attr go_eCharger stateFormat {sprintf(&amp;quot;%s: %s Current %d A, ETO=%.1f kWh&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==1?&amp;quot;ready, waiting for car&amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==2?&amp;quot;car loading&amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==3?&amp;quot;waiting for car&amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==4?&amp;quot;charge finished, but connected&amp;quot;:&amp;quot;unknown&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==1?&amp;quot;error RCCB: &amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==3?&amp;quot;error PHASE: &amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==8?&amp;quot;error NO_GROUND: &amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==10?&amp;quot;error INTERNAL: &amp;quot;:&amp;quot;&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;amp&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;eto&amp;quot;,0)/10,\&lt;br /&gt;
&amp;quot;&amp;quot;\&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das dürfte so das Wichtigste sein, um die Werte auszulesen.&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=HTTPMOD&amp;diff=27840</id>
		<title>HTTPMOD</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=HTTPMOD&amp;diff=27840"/>
		<updated>2018-09-12T20:41:16Z</updated>

		<summary type="html">&lt;p&gt;C2j2: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Extract information from devices with an HTTP interface (or, more generic, from any URL) or send information to such devices &lt;br /&gt;
|ModType=d&lt;br /&gt;
|ModCmdRef=HTTPMOD&lt;br /&gt;
|ModForumArea=Sonstiges&lt;br /&gt;
|ModTechName=98_HTTPMOD.pm&lt;br /&gt;
|ModOwner=StefanStrobel ({{Link2FU|3960|Forum}} / [[Benutzer:StefanStrobel|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
HTTPMOD provides a generic way to retrieve information from devices with an HTTP Interface and store them in Readings or send information to such devices. It queries a given URL with Headers and data defined by attributes. &lt;br /&gt;
&lt;br /&gt;
From the HTTP response it extracts readings named in attributes using Regexes, JSON or XPath parsing also defined by attributes.&lt;br /&gt;
&lt;br /&gt;
In an advanced [[Konfiguration|configuration]] the module can also send information to devices. To do this, a generic &amp;lt;code&amp;gt;set&amp;lt;/code&amp;gt; option can be configured using attributes. &lt;br /&gt;
&lt;br /&gt;
== Availability == &lt;br /&gt;
The module is part of the regular FHEM distribution.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
This module uses the non blocking HTTP function &amp;lt;code&amp;gt;HttpUtils_NonblockingGet&amp;lt;/code&amp;gt; provided by FHEM&#039;s [[HttpUtils]] in a new version published in December 2013.&lt;br /&gt;
If not already installed in your environment, please [[update]] FHEM or install it manually using appropriate commands from your environment.&lt;br /&gt;
Please also note that FHEM HttpUtils need the global attribute dnsServer to be set in order to work really non blocking even when dns requests can not be answered.&lt;br /&gt;
&lt;br /&gt;
== Define ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define &amp;lt;name&amp;gt; HTTPMOD &amp;lt;URL&amp;gt; &amp;lt;Interval&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The module connects to the given &amp;lt;code&amp;gt;URL&amp;lt;/code&amp;gt; every &amp;lt;code&amp;gt;Interval&amp;lt;/code&amp;gt; seconds, sends optional headers and data and then parses the response with regular expressions, xpath or json to set readings.&lt;br /&gt;
&lt;br /&gt;
URL can be &amp;quot;none&amp;quot; and Interval can be 0 if you prefer to only query data with a get command and not in a defined interval.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define PM HTTPMOD http://MyPoolManager/cgi-bin/webgui.fcgi 60&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Set-Commands ==&lt;br /&gt;
can be defined using attributes, see advanced configuration&lt;br /&gt;
&lt;br /&gt;
If you set the attribute enableControlSet to 1, the following additional built in set commands are available:&lt;br /&gt;
;interval&lt;br /&gt;
:set new interval time in seconds and restart the timer&lt;br /&gt;
;reread&lt;br /&gt;
:request the defined URL and try to parse it just like the automatic update would do it every Interval seconds without modifying the running timer.&lt;br /&gt;
;stop&lt;br /&gt;
:stop interval timer.&lt;br /&gt;
;start&lt;br /&gt;
:restart interval timer to call GetUpdate after interval seconds&lt;br /&gt;
;upgradeAttributes&lt;br /&gt;
:convert outdated attributes for older HTTPMOD-Versions that are still defined for this device from the old syntax to the new one.&lt;br /&gt;
:attributes with the description &amp;quot;this attribute should not be used anymore&amp;quot; or similar will be translated to the new syntax, e.g. readingsName1 to reading01Name.&lt;br /&gt;
;storeKeyValue&lt;br /&gt;
:stores a key value pair in an obfuscated form in the file system. Such values can then be used in replacements where the mode is &amp;quot;key&amp;quot; e.g. to avoid storing passwords in the configuration in clear text&lt;br /&gt;
&lt;br /&gt;
== Get-Commands ==&lt;br /&gt;
can be defined using attributes, see advanced configuration&lt;br /&gt;
&lt;br /&gt;
== simple Attributes ==&lt;br /&gt;
;enableControlSet&lt;br /&gt;
:enables the built in set commands &#039;&#039;interval&#039;&#039;, &#039;&#039;stop&#039;&#039;, &#039;&#039;start&#039;&#039;, &#039;&#039;reread&#039;&#039;, &#039;&#039;upgradeAttributes&#039;&#039;, &#039;&#039;storeKeyValue&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
;enableCookies&lt;br /&gt;
:enables the cookie handling inside HTTPMOD. It is advisable to always set this attribute and allow HTTPMOD to track the state of cookies and set them for following HTTP-requests&lt;br /&gt;
&lt;br /&gt;
;enforceGoodReadingNames&lt;br /&gt;
:makes sure that HTTPMOD only creates readings that are allowd for Fhem (especially if reading names are dynamically created from JSON object names with extractAllJSON. It is advisable to always set this attribute.&lt;br /&gt;
&lt;br /&gt;
;handleRedirects&lt;br /&gt;
:enables the redirect handling inside HTTPMOD which should be used together with the cookie handling of HTTPMOD. HTTPMOD will then automatically follow redirects from a web server and keep track of cookies at the same time. It is advisable to always set this attribute.&lt;br /&gt;
&lt;br /&gt;
;requestHeader.* &lt;br /&gt;
:Define an additional HTTP Header to set in the HTTP request&lt;br /&gt;
&lt;br /&gt;
;requestData&lt;br /&gt;
:POST Data to be sent in the request. If not defined, it will be a GET request as defined in HttpUtils used by this module&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+(-[0-9]+)?Name&lt;br /&gt;
:the name of a reading to extract with the corresponding readingRegex&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?OExpr&lt;br /&gt;
:defines an expression that is used in an eval to compute the readings value. The raw value will be in the variable $val.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?OMap&lt;br /&gt;
:Output Map. Defines a mapping from raw to visible values like &amp;quot;0:mittig, 1:oberhalb, 2:unterhalb&amp;quot;. If specified as readingOMap then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*OMap.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?Format&lt;br /&gt;
:Defines a format string that will be used in sprintf to format a reading value. If specified as readingFormat then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*Format.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?Decode&lt;br /&gt;
:defines an encoding to be used in a call to the perl function decode to convert the raw data string read from the device to a reading. This can be used if the device delivers strings in an encoding like cp850 instead of utf8.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?Encode&lt;br /&gt;
:defines an encoding to be used in a call to the perl function encode to convert the raw data string read from the device to a reading. This can be used if the device delivers strings in an encoding like cp850 and after decoding it you want to reencode it to e.g. utf8.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+Regex&lt;br /&gt;
:defines the regex to be used for extracting the reading. The value to extract should be in a capture group / sub expression &lt;br /&gt;
:e.g. ([\d\.]+) in the above example. Multiple capture groups will create multiple readings (see explanation above)&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+XPath&lt;br /&gt;
:defines an xpath to one or more readings when parsing HTML data (see examples below)&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+XPath-Strict&lt;br /&gt;
:defines an xpath to one or more readings when parsing XML data (see examples below)&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+JSON&lt;br /&gt;
:defines a path to the JSON object wanted by concatenating the object names with an underscore as delimiter (see the example below)&lt;br /&gt;
&lt;br /&gt;
;noShutdown&lt;br /&gt;
:pass the noshutdown flag to HTTPUtils for webservers that need it (some embedded webservers only deliver empty pages otherwise)&lt;br /&gt;
&lt;br /&gt;
;disable&lt;br /&gt;
:stop doing automatic HTTP requests while this attribute is set to 1&lt;br /&gt;
&lt;br /&gt;
;timeout&lt;br /&gt;
:time in seconds to wait for an answer. Default value is 2&lt;br /&gt;
&lt;br /&gt;
;do_not_notify&lt;br /&gt;
&lt;br /&gt;
;readingFnAttributes&lt;br /&gt;
&lt;br /&gt;
== Simple Configuration of HTTP Devices ==&lt;br /&gt;
If your device expects special HTTP-headers then specify them as &amp;lt;code&amp;gt;attr requestHeader1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;attr requestHeaderX&amp;lt;/code&amp;gt;.&lt;br /&gt;
If your Device expects an HTTP POST instead of HTTP GET then the POST-data can be specified as &amp;lt;code&amp;gt;attr requestData&amp;lt;/code&amp;gt;.&lt;br /&gt;
To get the readings, specify pairs of &amp;lt;code&amp;gt;attr readingXName&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;attr readingXRegex&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attr readingXXPath&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attr readingXXPath-Strict&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;attr readingXJSON&amp;lt;/code&amp;gt; to define which readings you want to extract from the HTTP response and how to extract them. (The old syntax &amp;lt;code&amp;gt;attr readingsNameX&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;attr readingsRegexX&amp;lt;/code&amp;gt; is still supported but the new one with &amp;lt;code&amp;gt;attr readingXName&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;attr readingXRegex&amp;lt;/code&amp;gt; should be preferred. The actual values to be extracted have to be sub expressions within () in the regex (see example below)&lt;br /&gt;
&lt;br /&gt;
=== Example for a PoolManager 5: ===&lt;br /&gt;
The PoolManager Web GUI can be queried with HTTP POST Requests like this one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
POST /cgi-bin/webgui.fcgi HTTP/1.1&lt;br /&gt;
Host: 192.168.70.90&lt;br /&gt;
Accept: */*&lt;br /&gt;
Content-Type: application/json;charset=UTF-8&lt;br /&gt;
Content-Length: 60&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;get&amp;quot; :[&amp;quot;34.4001.value&amp;quot; ,&amp;quot;34.4008.value&amp;quot; ,&amp;quot;34.4033.value&amp;quot;]}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting HTTP Response would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Content-type: application/json; charset=UTF-8&lt;br /&gt;
Expires: 0&lt;br /&gt;
Cache-Control: no-cache&lt;br /&gt;
Date: Sun, 12 Jan 2014 12:23:11 GMT&lt;br /&gt;
Server: lighttpd/1.4.26&lt;br /&gt;
Content-Length: 179&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;data&amp;quot;:	{&lt;br /&gt;
		&amp;quot;34.4001.value&amp;quot;:	&amp;quot;7.00&amp;quot;,&lt;br /&gt;
		&amp;quot;34.4008.value&amp;quot;:	&amp;quot;0.52&amp;quot;,&lt;br /&gt;
		&amp;quot;34.4033.value&amp;quot;:	&amp;quot;24.8&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;status&amp;quot;:	{&lt;br /&gt;
		&amp;quot;code&amp;quot;:	0&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;event&amp;quot;:	{&lt;br /&gt;
		&amp;quot;type&amp;quot;:	1,&lt;br /&gt;
		&amp;quot;data&amp;quot;:	&amp;quot;48.30000.0&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To configure HTTPMOD for a PoolManager one would first define a PoolManager device with e.g. the name PM, the URL and an interval of e.g. 60 seconds. &lt;br /&gt;
&lt;br /&gt;
Then the data to be sent in the request needs to be defined because in this example the device expects a POST request so the query is not contained in the URL but in the request data.&lt;br /&gt;
&lt;br /&gt;
Also as seen above the device expects special HTTP headers in the request so these headers also need to be defined as &amp;lt;code&amp;gt;attr PM requestHeader1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;attr PM requestHeader2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then the names of the readings to be extracted would be set with attributes&lt;br /&gt;
&lt;br /&gt;
Then for each reading value to be extracted a regular expression needs to be set that will match the value in question within ().&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define PM HTTPMOD http://MyPoolManager/cgi-bin/webgui.fcgi 60&lt;br /&gt;
&lt;br /&gt;
attr PM enableControlSet 1&lt;br /&gt;
attr PM enableCookies 1&lt;br /&gt;
attr PM enforceGoodReadingNames 1&lt;br /&gt;
attr PM handleRedirects 1&lt;br /&gt;
&lt;br /&gt;
attr PM reading01Name PH&lt;br /&gt;
attr PM reading01Regex 34.4001.value&amp;quot;:[ \t]+&amp;quot;([\d\.]+)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
attr PM reading02Name CL&lt;br /&gt;
attr PM reading02Regex 34.4008.value&amp;quot;:[ \t]+&amp;quot;([\d\.]+)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
attr PM reading03Name3TEMP&lt;br /&gt;
attr PM reading03Regex 34.4033.value&amp;quot;:[ \t]+&amp;quot;([\d\.]+)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
attr PM requestData {&amp;quot;get&amp;quot; :[&amp;quot;34.4001.value&amp;quot; ,&amp;quot;34.4008.value&amp;quot; ,&amp;quot;34.4033.value&amp;quot;, &amp;quot;14.16601.value&amp;quot;, &amp;quot;14.16602.value&amp;quot;]}&lt;br /&gt;
attr PM requestHeader1 Content-Type: application/json&lt;br /&gt;
attr PM requestHeader2 Accept: */*&lt;br /&gt;
attr PM stateFormat {sprintf(&amp;quot;%.1f Grad, PH %.1f, %.1f mg/l Chlor&amp;quot;, ReadingsVal($name,&amp;quot;TEMP&amp;quot;,0), ReadingsVal($name,&amp;quot;PH&amp;quot;,0), ReadingsVal($name,&amp;quot;CL&amp;quot;,0))}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example for AmbientMonitor ===&lt;br /&gt;
AmbientMonitor is a webbased visualisation for sensors connected to an Arduino device. Its web interface can also be queried with HTTMOD to grab the data into readings.&lt;br /&gt;
&lt;br /&gt;
This example was provided by locutus. The hardware configuration is an Arduino + Ethercard with ENC28J60 Controller + DHT22 Sensor and software can be downloaded from https://github.com/lucadentella/AmbientMonitor&lt;br /&gt;
&lt;br /&gt;
In this example an HTTP GET is sufficent, so no &amp;lt;code&amp;gt;requestData&amp;lt;/code&amp;gt; is needed. The device provides temperature and humidity readings in an HTTP response that looks like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.0 200 OK &lt;br /&gt;
Content-Type: text/html &lt;br /&gt;
&lt;br /&gt;
myCB({&#039;temperature&#039;:22.00,&#039;humidity&#039;:46.00})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the definition could be:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define AmbientMonitor HTTPMOD http://192.168.1.221/?callback=? 300&lt;br /&gt;
&lt;br /&gt;
attr AmbientMonitor enableControlSet 1&lt;br /&gt;
attr AmbientMonitor enableCookies 1&lt;br /&gt;
attr AmbientMonitor enforceGoodReadingNames 1&lt;br /&gt;
attr AmbientMonitor handleRedirects 1&lt;br /&gt;
&lt;br /&gt;
attr AmbientMonitor requestHeader Content-Type: application/json&lt;br /&gt;
attr AmbientMonitor reading1Name Temperatur&lt;br /&gt;
attr AmbientMonitor reading1Regex temperature&#039;:([\d\.]+)&lt;br /&gt;
attr AmbientMonitor reading2Name Feuchtigkeit&lt;br /&gt;
attr AmbientMonitor reading2Regex humidity&#039;:([\d\.]+)&lt;br /&gt;
attr AmbientMonitor stateFormat {sprintf(&amp;quot;Temperatur %.1f C, Feuchtigkeit %.1f %&amp;quot;, ReadingsVal($name,&amp;quot;Temperatur&amp;quot;,0), ReadingsVal($name,&amp;quot;Feuchtigkeit&amp;quot;,0))}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== formatting and manipulating values / readings ==&lt;br /&gt;
Values that are parsed from an HTTP response can be further treated or formatted with the following attributes:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?OExpr&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?OMap&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?Format&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?Decode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?Encode&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can all be specified for an individual reading, for all readings in one match (e.g. if a regular expression has several capture groups) or for all readings in a get command (defined by getXX) or for all readings in the main reading list (defined by readingXX):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading01Format %.1f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will format the reading with the name specified by the attribute reading01Name to be numerical with one digit after the decimal point.&lt;br /&gt;
If the attribute reading01Regex is used and contains several capture groups then the format will be applied to all readings parsed by this regex unless these readings have their own format specified by reading01-1Format, reading01-2Format and so on.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading01-2Format %.1f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be used in cases where a regular expression specified as reading01regex contains several capture groups or an xpath specified as reading01XPath creates several readings. &lt;br /&gt;
In this case reading01-2Format specifies the format to be applied to the second match.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingFormat %.1f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
applies to all readings defined by a reading-Attribute that have no more specific format.&lt;br /&gt;
&lt;br /&gt;
If you need to do some calculation on a raw value before it is used as a reading, you can define the attribute &amp;lt;code&amp;gt;readingOExpr&amp;lt;/code&amp;gt;.&lt;br /&gt;
It defines a Perl expression that is used in an eval to compute the readings value. The raw value will be in the variable $val.&lt;br /&gt;
&lt;br /&gt;
Example for an expression:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM reading03OExpr $val * 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Just like in the above example of the readingFormat attributes, readingOExpr and the other following attributes can be applied on several levels.&lt;br /&gt;
&lt;br /&gt;
To map a numerical value to a name, you can use the readingOMap attribute. &lt;br /&gt;
It defines a mapping from raw to visible values like &amp;quot;0:mittig, 1:oberhalb, 2:unterhalb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example for a map:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM reading02-3OMap 0:kalt, 1:warm, 2:sehr warm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To convert character sets, the module can first decode a string read from the device and then encode it again. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM getDecode UTF-8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This applies to all readings defined for Get-Commands.&lt;br /&gt;
&lt;br /&gt;
== Some help with Regular Expressions ==&lt;br /&gt;
{{Randnotiz|RNTyp=y|RNText=Starting with version &#039;&#039;2018-02-10&#039;&#039; the internal that holds the HTTP response is no longer called &#039;&#039;&#039;&#039;&#039;buf&#039;&#039;&#039;&#039;&#039; but rather &#039;&#039;&#039;&#039;&#039;httpbody&#039;&#039;&#039;&#039;&#039;, and it is only displayed when attribute &#039;&#039;&#039;&#039;&#039;showBody&#039;&#039;&#039;&#039;&#039; is set to &amp;quot;1&amp;quot;.}}&lt;br /&gt;
If HTTPMOD seems not to work and the FHEM Logfile contains a message like  &lt;br /&gt;
:&amp;lt;code&amp;gt;HTTPMOD: Response didn&#039;t match Reading ...&amp;lt;/code&amp;gt;&lt;br /&gt;
then you should check if the value you want to extract is read into the internal with the name buf. Internals are visible when you click on the defined HTTPMOD Device. buf is an internal variable that contains the HTTP Response read. If the value is there and you get the mentioned message then probably something is wrong with your regular expression. Please note that buf might contain special characters like newlines but they are not shown in fhemweb. If you are new to regular expressions then the introduction at http://perldoc.perl.org/perlretut.html might be helpful. &lt;br /&gt;
&lt;br /&gt;
For a typical HTTPMOD use case where you want to extract a number out of a HTTP-Response you can use something like &amp;lt;code&amp;gt;[\d\.]+&amp;lt;/code&amp;gt; to match the number itself. The expression matches the number characters (&amp;lt;code&amp;gt;\d&amp;lt;/code&amp;gt;) or a &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt; if one of these characters occurs at least once. &lt;br /&gt;
&lt;br /&gt;
To tell HTTPMOD that the number is what you want to use for the reading, you have to put the expression in between &amp;lt;code&amp;gt;()&amp;lt;/code&amp;gt;. A &amp;lt;code&amp;gt;([\d\.]+)&amp;lt;/code&amp;gt; alone would match the longest number in the HTTP Response which is very likely not the number you are looking for so you need to add something to the expression to give it a context and define how to find the number that you are looking for.&lt;br /&gt;
&lt;br /&gt;
If there is a title text before the number or a special text after the number you can put this in the regex. In one of the examples above &amp;lt;code&amp;gt;humidity&#039;:([\d\.]+)&amp;lt;/code&amp;gt; is looking for the number that immediately follows the text &amp;lt;code&amp;gt;humidity&#039;:&amp;lt;/code&amp;gt; without any blanks in between.&lt;br /&gt;
Be careful if the text you are getting from your device contains special characters like newline. You don&#039;t see such special characters in the fhem webinterface as contents of the internal buf but they might cause your regular expression to fail. &lt;br /&gt;
&lt;br /&gt;
If you have trouble defining a regular expression that matches a certain name, then many complicated characters and then a number, it might be helpful to use a negation in matching like &amp;lt;code&amp;gt;temp[^\d]+([\d\.]).*&amp;lt;/code&amp;gt;. In this examle &amp;lt;code&amp;gt;[^\d]+&amp;lt;/code&amp;gt; means any character that is not a numerical digit, more than once.&lt;br /&gt;
&lt;br /&gt;
=== Regular Expressions with multiple capture Groups ===&lt;br /&gt;
The regular expressions used in the above example for a Poolmanager will take the value that matches one capture group. This is the part of the regular expression inside (). In the above example &amp;quot;([\d\.]+)&amp;quot; refers to numerical digits or points between double quotation marks. Only the string consiting of digits and points will match inside (). This piece is assigned to the reading.&lt;br /&gt;
        &lt;br /&gt;
You can also use regular expressions that have several capture groups which might be helpful when parsing tables. In this case an attribute like &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading02Regex something[ \t]+([\d\.]+)[ \t]+([\d\.]+)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
could match two numbers. When you specify only one reading02Name like &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading02Name Temp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the name Temp will be used with the extension -1 and -2 thus giving a reading Temp-1 for the first number and Temp-2 for the second. You can also specify individual names for several readings that get parsed from one regular expression with several capture groups by defining attributes &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading02-1Name&lt;br /&gt;
reading02-2Name&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The same notation can be used for formatting attributes like readingXOMap, readingXFormat and so on.&lt;br /&gt;
&lt;br /&gt;
The usual way to define readings is however to have an individual regular expression with just one capture group per reading as shown in the above example.&lt;br /&gt;
&lt;br /&gt;
== Parsing JSON ==&lt;br /&gt;
    &lt;br /&gt;
If a webservice delivers data in JSON format, HTTPMOD can directly parse JSON which might be easier in this case than definig regular expressions.&lt;br /&gt;
The next example shows the data that can be requested from a Poolmanager with the following partial configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define test2 HTTPMOD none 0&lt;br /&gt;
attr test2 get01Name Chlor&lt;br /&gt;
attr test2 getURL http://192.168.70.90/cgi-bin/webgui.fcgi&lt;br /&gt;
attr test2 getHeader1 Content-Type: application/json&lt;br /&gt;
attr test2 getHeader2 Accept: */*&lt;br /&gt;
attr test2 getData {&amp;quot;get&amp;quot; :[&amp;quot;34.4008.value&amp;quot;]}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The data in the HTTP response looks like this:&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;data&amp;quot;: {&lt;br /&gt;
			&amp;quot;34.4008.value&amp;quot;: &amp;quot;0.25&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;status&amp;quot;:       {&lt;br /&gt;
			&amp;quot;code&amp;quot;: 0&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;event&amp;quot;:        {&lt;br /&gt;
			&amp;quot;type&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;data&amp;quot;: &amp;quot;48.30000.0&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the classic way to extract the value 0.25 into a reading with the name Chlor with a regex would have been&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr test2 get01Regex 34.4008.value&amp;quot;:[ \t]+&amp;quot;([\d\.]+)&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with JSON you can write &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr test2 get01JSON data_34.4008.value &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which will create a reading with the Name &amp;quot;Chlor&amp;quot; (as shown above) and take the value 0.25 from the JSON string.&lt;br /&gt;
&lt;br /&gt;
or if you don&#039;t care about the naming of your readings, you can simply extract all JSON data with &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr test2 extractAllJSON&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which would apply to all data read from this device and create the following readings out of the HTTP response shown above:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| data_34.4008.value || 0.25&lt;br /&gt;
|-&lt;br /&gt;
| event_data || 48.30000.0&lt;br /&gt;
|-&lt;br /&gt;
| event_type || 1&lt;br /&gt;
|-&lt;br /&gt;
| status_code || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
or you can specify&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr test2 get01ExtractAllJSON&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which would only apply to all data read as response to the get command defined as get01.        &lt;br /&gt;
&lt;br /&gt;
It might seem very simple at first sight to use extractAllJSON but if you prefer readings with a meaningful name you should instead define these readings with readingXXName and readingXXJSON or getXXName and getXXJSON individually. Of Course it would be possible to create additional user readings outside HTTPMOD but doing calculations, naming and formatting inside HTTPMOD is more efficient.&lt;br /&gt;
&lt;br /&gt;
=== JSON Lists ===&lt;br /&gt;
&lt;br /&gt;
imagine the HTTP Response contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
{ &amp;quot;power&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
  &amp;quot;modes&amp;quot;:[&amp;quot;Off&amp;quot;,&amp;quot;SimpleColor&amp;quot;,&amp;quot;RainbowChase&amp;quot;],&lt;br /&gt;
  &amp;quot;code1&amp;quot;:3,&lt;br /&gt;
  &amp;quot;code2&amp;quot;:4&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then a configuration like &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr device reading01JSON modes &lt;br /&gt;
attr device reading01Name Mode &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will create a list of Subreadings just like a regex with multiple matches can create multiple subreadings:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Mode-1 || Off&lt;br /&gt;
|-&lt;br /&gt;
| Mode-2  || SimpleColor&lt;br /&gt;
|-&lt;br /&gt;
| Mode-3 || RainbowChase &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
if you don&#039;t want several subreadings but one reading that contains the list of modes, you can specify a recombine expression:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr device reading01Name Modes &lt;br /&gt;
attr device reading01RecombineExpr join &amp;quot;,&amp;quot;, @matchlist &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which will create one reading containing a list:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Modes || Off,SimpleColor,RainbowChase&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
JSON parsing specifications also don&#039;t Need to match exactly. If there is no exact match for a defined reading, the HTTPMOD will try to Interpret the specification as a regex and look for json object paths that match the specification as a regex. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr device reading01Name CodeElem&lt;br /&gt;
attr device reading01JSON code&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which will create a list of readings:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| CodeElem-1|| 3&lt;br /&gt;
|-&lt;br /&gt;
| CodeElem-2  || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
and of course they could also be recombined into one reading with a RecombineExpr Attribute.&lt;br /&gt;
&lt;br /&gt;
== Parsing http / XML using xpath ==&lt;br /&gt;
Another alternative to regex parsing is the use of XPath to extract values from HTTP responses.&lt;br /&gt;
The following example shows how XML data can be parsed with XPath-Strict or HTML Data can be parsed with XPath.&lt;br /&gt;
Both work similar and the example uses XML Data parsed with the XPath-Strict option:&lt;br /&gt;
&lt;br /&gt;
If The XML data in the HTTP response looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;root xmlns:foo=&amp;quot;http://www.foo.org/&amp;quot; xmlns:bar=&amp;quot;http://www.bar.org&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;actors&amp;gt;&lt;br /&gt;
		&amp;lt;actor id=&amp;quot;1&amp;quot;&amp;gt;Peter X&amp;lt;/actor&amp;gt;&lt;br /&gt;
		&amp;lt;actor id=&amp;quot;2&amp;quot;&amp;gt;Charles Y&amp;lt;/actor&amp;gt;&lt;br /&gt;
		&amp;lt;actor id=&amp;quot;3&amp;quot;&amp;gt;John Doe&amp;lt;/actor&amp;gt;&lt;br /&gt;
	&amp;lt;/actor&amp;gt;&lt;br /&gt;
&amp;lt;/root&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with XPath you can write        &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr htest reading01Name Actor&lt;br /&gt;
attr htest reading01XPath-Strict //actor[2]/text()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a reading with the Name &amp;quot;Actor&amp;quot; and the value &amp;quot;Charles Y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Since XPath specifications can define several values / matches, HTTPMOD can also interpret these and store them in multiple readings:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr htest reading01Name Actor&lt;br /&gt;
attr htest reading01XPath-Strict //actor/text()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will create the readings &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Actor-1 || Peter X&lt;br /&gt;
|-&lt;br /&gt;
| Actor-2 || Charles Y&lt;br /&gt;
|-&lt;br /&gt;
| Actor-3 || John Doe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Further replacements of URL, header or post data ==&lt;br /&gt;
sometimes it might be helpful to dynamically change parts of a URL, HTTP header or post data depending on existing readings, internals or &lt;br /&gt;
perl expressions at runtime. This might be needed to pass further variables to a server, a current date or other things. &lt;br /&gt;
&lt;br /&gt;
To support this HTTPMOD offers generic replacements that are applied to a request before it is sent to the server. A replacement can be defined with the attributes &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;replacement[0-9]*Regex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[gs]et[0-9]*Replacement[0-9]*Value&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a replacement always replaces a match of a regular expression. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;replacement[0-9]*Mode:&#039;&#039;&#039;&lt;br /&gt;
The way the replacement value is defined can be specified with the replacement mode.&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;reading&amp;lt;/code&amp;gt;, then the corresponding &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt; is interpreted as the name of a &#039;&#039;reading&#039;&#039; of the same device or as &#039;&#039;device:reading&#039;&#039; to refer to another device.&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;internal&amp;lt;/code&amp;gt;, then the corresponding &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt; is interpreted as the name of an &#039;&#039;internal&#039;&#039; of the same device or as &#039;&#039;device:internal&#039;&#039; to refer to another device.&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt;, then the corresponding &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt; is interpreted as a static text&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;expression&amp;lt;/code&amp;gt;, then the corresponding &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt; is evaluated as a perl expression to compute the replacement. Inside such a replacement expression it is possible to refer to capture groups of the replacement regex.&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt;, then the module will use a value from a key / value pair that is stored in an obfuscated form in the file system with the set storeKeyValue command. This might be useful for storing passwords.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr mydevice getData {&amp;quot;get&amp;quot; :[&amp;quot;%%value%%.value&amp;quot;]}&lt;br /&gt;
attr mydevice replacement01Mode text&lt;br /&gt;
attr mydevice replacement01Regex %%value%%&lt;br /&gt;
&lt;br /&gt;
attr mydevice get01Name Chlor&lt;br /&gt;
attr mydevice get01Replacement01Value 34.4008&lt;br /&gt;
&lt;br /&gt;
attr mydevice get02Name Something&lt;br /&gt;
attr mydevice get02Replacement01Value 31.4024&lt;br /&gt;
&lt;br /&gt;
attr mydevice get05Name profile&lt;br /&gt;
attr mydevice get05URL http://www.mydevice.local/getprofile?password=%%password%%&lt;br /&gt;
attr mydevice replacement02Mode key&lt;br /&gt;
attr mydevice replacement02Regex %%password%%&lt;br /&gt;
attr mydevice get05Replacement02Value password&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;        &lt;br /&gt;
&lt;br /&gt;
defines that &amp;lt;code&amp;gt;%%value%%&amp;lt;/code&amp;gt; will be replaced by a static text.&lt;br /&gt;
&lt;br /&gt;
All Get commands will be HTTP post requests of a similar form. Only the &amp;lt;code&amp;gt;%%value%%&amp;lt;/code&amp;gt; will be different from get to get.&lt;br /&gt;
The first get will set the reading named Chlor and for the request it will take the generic getData and replace %%value%% with 34.4008.&lt;br /&gt;
&lt;br /&gt;
A second get will look the same except a different name and replacement value.&lt;br /&gt;
&lt;br /&gt;
With the command &amp;lt;code&amp;gt;set storeKeyValue password geheim&amp;lt;/code&amp;gt; you can store the password geheim in an obfuscated form in the file system. &lt;br /&gt;
To use this password and send it in a request you can use the above replacement with mode key. The value password will then refer to the ofuscated string stored with the key password.&lt;br /&gt;
&lt;br /&gt;
The mode &amp;lt;code&amp;gt;expression&amp;lt;/code&amp;gt; allows you to define your own replacement syntax:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;        &lt;br /&gt;
attr mydevice replacement01Mode expression&lt;br /&gt;
attr mydevice replacement01Regex {{([^}]+)}}&lt;br /&gt;
attr mydevice replacement01Value ReadingsVal(&amp;quot;mydevice&amp;quot;, $1, &amp;quot;&amp;quot;)&lt;br /&gt;
attr mydevice getData {&amp;quot;get&amp;quot; :[&amp;quot;{{temp}}.value&amp;quot;]}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;      &lt;br /&gt;
&lt;br /&gt;
In this example any &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{name}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; in a URL, header or post data will be passed on to the perl function ReadingsVal &lt;br /&gt;
which uses the string between &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; as second parameter. This way one defined replacement can be used for many different&lt;br /&gt;
readings.&lt;br /&gt;
&lt;br /&gt;
HTTPMOD has two built in replacements: One for session Ids and another one for the input value in a set command.&lt;br /&gt;
The placeholder $sid is always replaced with the internal &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt; which contains the session id after it is extracted from a previous HTTP response. &lt;br /&gt;
If you don&#039;t like to use the placeholder $sid then you can define your own replacement for example like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr mydevice replacement01Mode internal&lt;br /&gt;
attr mydevice replacement01Regex %session%&lt;br /&gt;
attr mydevice replacement01Value sid&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;      &lt;br /&gt;
&lt;br /&gt;
Now the internal &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt; will be used as a replacement for the placeholder %session%.&lt;br /&gt;
&lt;br /&gt;
In the same way a value that is passed to a set-command can be put into a request with a user defined replacement. &lt;br /&gt;
In this case the internal &amp;lt;code&amp;gt;$hash-&amp;gt;{value}&amp;lt;/code&amp;gt; will contain the value passed to the set command. &lt;br /&gt;
&amp;lt;code&amp;gt;$hash-&amp;gt;{value}&amp;lt;/code&amp;gt; might even be a string containing several values that could be put into several different positions in a request by using user defined replacements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Other example : steering a pellet stove from Rika&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The stove API of Rika on https://www.rika-firenet.com/web/ delivers a JSON string with all settings and values, and can be piloted with a data string containing all the &amp;quot;set&amp;quot; values at once.&lt;br /&gt;
&lt;br /&gt;
Delivered JSON on get https://www.rika-firenet.com/api/client/xxxxxxxx/status : (xxxxxxxx must be replaced with the unique stove ID)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Vorzimmer&amp;quot;,&lt;br /&gt;
    &amp;quot;stoveID&amp;quot;: &amp;quot;xxxxxxxxx&amp;quot;,&lt;br /&gt;
    &amp;quot;lastSeenMinutes&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;lastConfirmedRevision&amp;quot;: 1504385700,&lt;br /&gt;
    &amp;quot;controls&amp;quot;: {&lt;br /&gt;
        &amp;quot;revision&amp;quot;: 1504385700,&lt;br /&gt;
        &amp;quot;onOff&amp;quot;: true,&lt;br /&gt;
        &amp;quot;operatingMode&amp;quot;: 2,&lt;br /&gt;
        &amp;quot;heatingPower&amp;quot;: 65,&lt;br /&gt;
        &amp;quot;targetTemperature&amp;quot;: 24,&lt;br /&gt;
        &amp;quot;heatingTimesActive&amp;quot;: false,&lt;br /&gt;
        &amp;quot;heatingTimesActiveForComfort&amp;quot;: true,&lt;br /&gt;
        &amp;quot;setBackTemperature&amp;quot;: 18,&lt;br /&gt;
        &amp;quot;convectionFan1Active&amp;quot;: false,&lt;br /&gt;
        &amp;quot;convectionFan1Level&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;convectionFan1Area&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;convectionFan2Active&amp;quot;: false,&lt;br /&gt;
        &amp;quot;convectionFan2Level&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;convectionFan2Area&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;frostProtectionActive&amp;quot;: false,&lt;br /&gt;
        &amp;quot;frostProtectionTemperature&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;sensors&amp;quot;: {&lt;br /&gt;
        &amp;quot;statusError&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;statusWarning&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;statusService&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;statusMainState&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;statusSubState&amp;quot;: 3,&lt;br /&gt;
        &amp;quot;statusFrostStarted&amp;quot;: false,&lt;br /&gt;
        &amp;quot;inputFlameTemperature&amp;quot;: 21,&lt;br /&gt;
        &amp;quot;inputRoomTemperature&amp;quot;: 21,&lt;br /&gt;
        &amp;quot;inputExternalRequest&amp;quot;: true,&lt;br /&gt;
        &amp;quot;outputDischargeMotor&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;outputInsertionMotor&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;outputIDFan&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;outputAirFlaps&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;outputIgnition&amp;quot;: false,&lt;br /&gt;
        &amp;quot;parameterStoveTypeNumber&amp;quot;: 13,&lt;br /&gt;
        &amp;quot;parameterVersionMainBoard&amp;quot;: 223,&lt;br /&gt;
        &amp;quot;parameterVersionTFT&amp;quot;: 223,&lt;br /&gt;
        &amp;quot;parameterRuntimePellets&amp;quot;: 11,&lt;br /&gt;
        &amp;quot;parameterRuntimeLogs&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;parameterFeedRateTotal&amp;quot;: 17,&lt;br /&gt;
        &amp;quot;parameterFeedRateService&amp;quot;: 683,&lt;br /&gt;
        &amp;quot;parameterOnOffCycles&amp;quot;: 2&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;stoveType&amp;quot;: &amp;quot;DOMO MultiAir&amp;quot;,&lt;br /&gt;
    &amp;quot;stoveFeatures&amp;quot;: {&lt;br /&gt;
        &amp;quot;multiAir1&amp;quot;: true,&lt;br /&gt;
        &amp;quot;multiAir2&amp;quot;: true,&lt;br /&gt;
        &amp;quot;insertionMotor&amp;quot;: false,&lt;br /&gt;
        &amp;quot;airFlaps&amp;quot;: false,&lt;br /&gt;
        &amp;quot;logRuntime&amp;quot;: false&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Data string to send to https://www.rika-firenet.com/api/client/xxxxxxxx/controls in order to set values:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
heatingTimesActiveForComfort=true&amp;amp;frostProtectionTemperature=3&amp;amp;setBackTemperature=18&amp;amp;targetTemperature=24&amp;amp;convectionFan2Level=0&amp;amp;convectionFan2Active=false&amp;amp;convectionFan1Level=0&amp;amp;onOff=true&amp;amp;convectionFan1Active=false&amp;amp;convectionFan2Area=0&amp;amp;revision=1505550101&amp;amp;heatingTimesActive=false&amp;amp;convectionFan1Area=0&amp;amp;frostProtectionActive=false&amp;amp;operatingMode=2&amp;amp;heatingPower=65&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code in 99_myUtils.pm:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
use JSON;&lt;br /&gt;
...&lt;br /&gt;
sub&lt;br /&gt;
replaceJSON ($$) {&lt;br /&gt;
   my ($valToReplace, $value) = @_;&lt;br /&gt;
&lt;br /&gt;
   #$value in the parameters is a default value&lt;br /&gt;
   #It has to be replaced through the real value nnn passed in the set command &amp;quot;set &amp;lt;device&amp;gt; valToset nnn&amp;quot;&lt;br /&gt;
   $value = InternalVal(&amp;quot;Ofen&amp;quot;, &amp;quot;value&amp;quot;, $value);&lt;br /&gt;
   Log3 (&amp;quot;Ofen&amp;quot;, 3, &amp;quot;replaceJSON Internalvalue: $value&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   #Force an update to avoid outdated revision number&lt;br /&gt;
   fhem (&amp;quot;get Ofen revision&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   #Get all the controls as json&lt;br /&gt;
   my $json = ReadingsVal(&amp;quot;Ofen&amp;quot;, &amp;quot;controlsJSON&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
   Log3 (&amp;quot;Ofen&amp;quot;, 3, &amp;quot;replaceJSON configsJSON: $json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   # When starting FHEM or rereading config, the reading controlsJSON is empty&lt;br /&gt;
   return if ($json eq &amp;quot;&amp;quot;); &lt;br /&gt;
&lt;br /&gt;
   my $decoded = decode_json($json);&lt;br /&gt;
   my $result;&lt;br /&gt;
   for my $key ( keys %$decoded ) {&lt;br /&gt;
      $result .= &amp;quot;$key=&amp;quot;;&lt;br /&gt;
      if ($key eq $valToReplace) {&lt;br /&gt;
         $result .= $value.&amp;quot;&amp;amp;&amp;quot;;&lt;br /&gt;
      } else {&lt;br /&gt;
         $result .= $decoded-&amp;gt;{$key}.&amp;quot;&amp;amp;&amp;quot;;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   chop($result); #remove last &amp;amp;&lt;br /&gt;
   Log3(&amp;quot;Ofen&amp;quot;, 3, &amp;quot;replaceJSON Result: $result&amp;quot;);&lt;br /&gt;
   return $result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Define stove in fhem:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
defmod Ofen HTTPMOD https://www.rika-firenet.com/api/client/xxxxxxxx/status 60&lt;br /&gt;
&lt;br /&gt;
attr Ofen enableCookies 1&lt;br /&gt;
attr Ofen reAuthRegex id=&amp;quot;login&amp;quot;|Unauthorized&lt;br /&gt;
attr Ofen sid01Data email=xx@xx&amp;amp;password=xx&lt;br /&gt;
attr Ofen sid01URL https://www.rika-firenet.com/web/login&lt;br /&gt;
&lt;br /&gt;
attr Ofen reading01JSON sensors_inputRoomTemperature&lt;br /&gt;
attr Ofen reading01Name RaumTemp&lt;br /&gt;
attr Ofen reading02JSON controls_setBackTemperature&lt;br /&gt;
attr Ofen reading02Name Absenkung&lt;br /&gt;
attr Ofen reading03JSON controls_frostProtectionTemperature&lt;br /&gt;
attr Ofen reading03Name Frostschutz&lt;br /&gt;
attr Ofen reading10Name controlsJSON&lt;br /&gt;
attr Ofen reading10Regex (?s)controls.*?({.*?})&lt;br /&gt;
&lt;br /&gt;
attr Ofen get09Name revision&lt;br /&gt;
attr Ofen get09URL https://www.rika-firenet.com/api/client/xxxxxxxx/status&lt;br /&gt;
&lt;br /&gt;
attr Ofen setURL https://www.rika-firenet.com/api/client/xxxxxxxx/controls&lt;br /&gt;
attr Ofen setData {{data}}&lt;br /&gt;
attr Ofen replacement01Mode expression&lt;br /&gt;
attr Ofen replacement01Regex {{data}}&lt;br /&gt;
&lt;br /&gt;
attr Ofen set11Name frostProtectionTemperature&lt;br /&gt;
attr Ofen set11Replacement01Value replaceJSON(&amp;quot;frostProtectionTemperature&amp;quot;, 2)&lt;br /&gt;
&lt;br /&gt;
attr Ofen set12Name targetTemperature&lt;br /&gt;
attr Ofen set12Replacement01Value replaceJSON(&amp;quot;targetTemperature&amp;quot;, 24)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A detailed explanation (in german) of the login process can be found here: [https://forum.fhem.de/index.php/topic,76220.msg682514.html#msg682514]&lt;br /&gt;
and the explanation of the other parameters here: [https://forum.fhem.de/index.php/topic,76220.msg685710.html#msg685710]&lt;br /&gt;
&lt;br /&gt;
== replacing reading values when they have not been updated / the device did not respond ==&lt;br /&gt;
If a device does not respond then the values stored in readings will keep the same and only their timestamp shows that they are outdated. &lt;br /&gt;
If you want to modify reading values that have not been updated for a number of seconds, you can use the attributes&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?MaxAge&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?MaxAgeReplacementMode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?MaxAgeReplacement&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every time the module tries to read from a device, it will also check if readings have not been updated &lt;br /&gt;
for longer than the &amp;lt;code&amp;gt;MaxAge&amp;lt;/code&amp;gt; attributes allow. If readings are outdated, the &amp;lt;code&amp;gt;MaxAgeReplacementMode&amp;lt;/code&amp;gt; defines how the affected&lt;br /&gt;
reading values should be replaced. &amp;lt;code&amp;gt;MaxAgeReplacementMode&amp;lt;/code&amp;gt; can be &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reading&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;internal&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;expression&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MaxAge&amp;lt;/code&amp;gt; specifies the number of seconds that a reading should remain untouched before it is replaced. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MaxAgeReplacement&amp;lt;/code&amp;gt; contains either a static text that is used as replacement value or a Perl expression that is evaluated to &lt;br /&gt;
give the replacement value. This can be used for example to replace a temperature that has not bee updated for more than 5 minutes &lt;br /&gt;
with the string &amp;quot;outdated - was 12&amp;quot;:        &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM readingMaxAge 300&lt;br /&gt;
attr PM readingMaxAgeReplacement &amp;quot;outdated - was &amp;quot; . $val&lt;br /&gt;
attr PM readingMaxAgeReplacementMode expression&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The variable &amp;lt;code&amp;gt;$val&amp;lt;/code&amp;gt; contains the value of the reading before it became outdated.&lt;br /&gt;
&lt;br /&gt;
Or to show that a device was offline:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr MyLight reading01Name color&lt;br /&gt;
attr MyLight reading01JSON result_02_color&lt;br /&gt;
attr MyLight reading01MaxAge 300&lt;br /&gt;
attr MyLight reading01MaxAgeReplacement &amp;quot;offline&amp;quot;&lt;br /&gt;
attr MyLight reading01MaxAgeReplacementMode text&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Note on determining how to send requests to a special device ==&lt;br /&gt;
If you don&#039;t know which URLs, headers or POST data your web GUI uses, you might try a local proxy like BurpSuite [http://portswigger.net/burp/ BurpSuite] to track requests and responses. This is a tedious task but probably the best way to achieve a successful result. &lt;br /&gt;
&lt;br /&gt;
Let us consider an example. The Telekom Speedport W724V has a login-site that is famous for being cumbersome. Burp allows to monitor each step in the login procedure. In the case of a speedport the following steps occur:&lt;br /&gt;
&lt;br /&gt;
First burp shows that a get command is issued&lt;br /&gt;
 ################################################################################################## &lt;br /&gt;
 GET / HTTP/1.1&lt;br /&gt;
 Host: speedport.ip&lt;br /&gt;
 Cache-Control: max-age=0&lt;br /&gt;
 Upgrade-Insecure-Requests: 1&lt;br /&gt;
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36&lt;br /&gt;
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8&lt;br /&gt;
 Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4&lt;br /&gt;
 Cookie: lang=de&lt;br /&gt;
 Connection: close  &lt;br /&gt;
In order to mimic the behavior of a real person calling the website HTTPMOD should copy all necessary steps. Host, Cookie and the GET-command are usually necessary. The same cannot be said of the User-Agent because the website can be called from any mobile or desktop computer. &lt;br /&gt;
&lt;br /&gt;
Then, the speedport will answer with a command that consists of several lines. By going through every line for every step in the login procedure one will finally arrive at the information that is necessary to successfully enter the login of the speedport (in case of the W724V, for example, it is necessary to copy a token called _httoken and to include the referer).&lt;br /&gt;
&lt;br /&gt;
== Advanced configuration to define a &amp;lt;code&amp;gt;set&amp;lt;/code&amp;gt; command and send data to a device ==&lt;br /&gt;
       &lt;br /&gt;
When a set option is defined by attributes, the module will use the value given to the set command and integrate it into an HTTP-Request that sends the value to the device. The definitions for URL, headers and post data can contain the placeholder $val which will be replaced by the value given to the set command.&lt;br /&gt;
&lt;br /&gt;
This can be as simple as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# No cyclic requests and no main URL needed in this example&lt;br /&gt;
define MyDevice HTTPMOD none 0&lt;br /&gt;
&lt;br /&gt;
attr MyDevice set01Name Licht&lt;br /&gt;
attr MyDevice set01URL http://192.168.1.22/switch=$val&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A user command &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
set MyDevice Licht 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will be translated into the http GET request&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
http://192.168.1.22/switch=1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a map would also be helpful, that translates on / off to 0 or 1 and allows the user to select on/of in fhemweb:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr MyDevive set01IMap 0:off, 1:on&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This also provides input validation to make sure that only on and off can be used with the set command.&lt;br /&gt;
&lt;br /&gt;
In more complex Scenarios you might need to login before sending a command and the Login might create a session id that has to be part of further requests either in the URL, in headers or in the post data.&lt;br /&gt;
&lt;br /&gt;
Extension to the above example for a PoolManager 5 where a set needs a session id in the URL and the values have to be passed in JSON strings as post data:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM set01Name HeizungSoll&lt;br /&gt;
attr PM set01URL http://MyPoolManager/cgi-bin/webgui.fcgi?sid=$sid&lt;br /&gt;
attr PM set01Hint 6,10,20,30&lt;br /&gt;
attr PM set01Min 6&lt;br /&gt;
attr PM set01Max 30&lt;br /&gt;
attr PM setHeader1 Content-Type: application/json&lt;br /&gt;
attr PM set01Data {&amp;quot;set&amp;quot; :{&amp;quot;34.3118.value&amp;quot; :&amp;quot;$val&amp;quot; }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example defines a set option with the name HeizungSoll.&lt;br /&gt;
By issuing &amp;lt;code&amp;gt;set PM HeizungSoll 10&amp;lt;/code&amp;gt; in FHEM, the value 10 will be sent in the defined HTTP&lt;br /&gt;
Post to URL &amp;lt;code&amp;gt;http://MyPoolManager/cgi-bin/webgui.fcgi&amp;lt;/code&amp;gt; in the Post Data as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
{&amp;quot;set&amp;quot; :{&amp;quot;34.3118.value&amp;quot; :&amp;quot;10&amp;quot; }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional attributes set01Min and set01Max define input validations that will be checked in the set function. &lt;br /&gt;
The optional attribute set01Hint will define a selection list for the FHEMweb GUI.&lt;br /&gt;
&lt;br /&gt;
The HTTP response to such a request will be ignored unless you specify the attribute &amp;lt;code&amp;gt;setParseResponse&amp;lt;/code&amp;gt; &lt;br /&gt;
for all set commands or &amp;lt;code&amp;gt;set01ParseResponse&amp;lt;/code&amp;gt; for the set command with number 01.&lt;br /&gt;
If the HTTP response to a set command is parsed then this is done like the parsing of responses to get commands and you can use the attributes ending e.g. on Format, Encode, Decode, OMap and OExpr to manipulate / format the values read.&lt;br /&gt;
&lt;br /&gt;
If a parameter to a set command is not numeric but should be passed on to the device as text, then you can specify the attribute setTextArg. For example: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM set01TextArg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a set command should not require a parameter at all, then you can specify the attribute NoArg. For example: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM set03Name On&lt;br /&gt;
attr PM set03NoArg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced configuration to create a valid session id that might be necessary ==&lt;br /&gt;
In simple cases logging in works with basic authentication. In the case HTTPMOD accepts a username and password as part of the URL in the form &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
http://User:Password@192.168.1.18/something&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However basic auth is seldom used. If you need to fill in a username and password in a HTML form and the session is then managed by a session id, here is how to configure this:&lt;br /&gt;
&lt;br /&gt;
when sending data to an HTTP-Device in a set, HTTPMOD will replace any &amp;lt;code&amp;gt;$sid&amp;lt;/code&amp;gt; in the URL, Headers and Post data with the internal &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt;. To authenticate towards the device and give this internal a value, you can use an optional multi step login procedure defined by the following attributes: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;sid[0-9]*URL&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sid[0-9]*Data.*&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sid[0-9]*Header.*&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sid[0-9]*IgnoreRedirects&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;idRegex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;idJSON&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;idXPath&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;idXPath-Strict&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set|sid)[0-9]*IdRegex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set|sid)[0-9]*IdJSON&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set|sid)[0-9]*IdXPath&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set|sid)[0-9]*IdXPath-Strict&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each step can have a URL, Headers, Post Data pieces and a Regex to extract a resulting Session ID into &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt;.&lt;br /&gt;
HTTPMOD will create a sorted list of steps (the numbers between sid and URL / Data / Header) and the loop through these steps and send the corresponding requests to the device. For each step a $sid in a Header or Post Data will be replaced with the current content of &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Using this feature, HTTPMOD can perform a forms based authentication and send user name, password or other necessary data to the device and save the session id for further requests.&lt;br /&gt;
        &lt;br /&gt;
To determine when this login procedure is necessary, HTTPMOD will first try to send a request without &lt;br /&gt;
doing the login procedure. If the result contains an error that authentication is necessary, then a login is performed. &lt;br /&gt;
To detect such an error in the HTTP response, you can again use a regular expression, JSON or XPath, this time with the attributes &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;reAuthRegex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reAuthJSON&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reAuthXPath&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reAuthXPath-Strict&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set)[0-9]*ReAuthRegex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set)[0-9]*ReAuthJSON&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set)[0-9]*ReAuthXPath&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set)[0-9]*ReAuthXPath-Strict&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reAuthJSON or reAuthXPath typically only extract one piece of data from a response. &lt;br /&gt;
If the existence of the specified piece of data is sufficent to start a login procedure, then nothing more needs to be defined to detect this situation. &lt;br /&gt;
If however the indicator is a status code that contains different values depending on a successful request and a failed request if a new authentication is needed, &lt;br /&gt;
then you can combine things like reAuthJSON with reAuthRegex. In this case the regex is only matched to the data extracted by JSON (or XPath). &lt;br /&gt;
This way you can easily extract the status code using JSON parsing and then specify the code that means &amp;quot;authentication needed&amp;quot; as a regular expression.&lt;br /&gt;
        &lt;br /&gt;
If for one step not all of the URL, Data or Header Attributes are set, then HTTPMOD tries to use a &lt;br /&gt;
&amp;lt;code&amp;gt;sidURL&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sidData.*&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sidHeader.*&amp;lt;/code&amp;gt; Attribute (without the step number after sid). This way parts that are the same for all steps don&#039;t need to be defined redundantly.&lt;br /&gt;
&lt;br /&gt;
=== Example for a multi step login procedure: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM reAuthRegex /html/dummy_login.htm &lt;br /&gt;
attr PM sidURL http://192.168.70.90/cgi-bin/webgui.fcgi?sid=$sid&lt;br /&gt;
attr PM sidHeader1 Content-Type: application/json&lt;br /&gt;
attr PM sid1IDRegex wui.init\(&#039;([^&#039;]+)&#039;&lt;br /&gt;
attr PM sid2Data {&amp;quot;set&amp;quot; :{&amp;quot;9.17401.user&amp;quot; :&amp;quot;fhem&amp;quot; ,&amp;quot;9.17401.pass&amp;quot; :&amp;quot;password&amp;quot; }}&lt;br /&gt;
attr PM sid3Data {&amp;quot;set&amp;quot; :{&amp;quot;35.5062.value&amp;quot; :&amp;quot;128&amp;quot; }}&lt;br /&gt;
attr PM sid4Data {&amp;quot;set&amp;quot; :{&amp;quot;42.8026.code&amp;quot; :&amp;quot;pincode&amp;quot; }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case HTTPMOD detects that a login is necessary by looking for the pattern /html/dummy_login.htm in the HTTP response. &lt;br /&gt;
If it matches, it starts a login sequence. In the above example all steps request the same URL. In step 1 only the defined Header is sent in an HTTP get request. The response will contain a session id that is extraced with the regex wui.init\(&#039;([^&#039;]+)&#039;.&lt;br /&gt;
&lt;br /&gt;
In the next step this session id is sent in a post request to the same URL where tha post data contains a username and password. The a third and a fourth request follow that set a value and a code. The result will be a valid and authorized session id that can be used in other requests where $sid is part of a URL, header or post data and will be replaced with the session id extracted above.&lt;br /&gt;
&lt;br /&gt;
In the special case where a session id is set as a HTTP-Cookie (with the header Set-cookie: in the HTTP response) HTTPMOD offers an even simpler way. With the attribute enableCookies a very basic cookie handling mechanism is activated that stores all cookies that the server sends to the HTTPMOD device and puts them back as cookie headers in the following requests.&lt;br /&gt;
&lt;br /&gt;
For such cases no sidIdRegex and no $sid in a user defined header is necessary.&lt;br /&gt;
&lt;br /&gt;
== Advanced configuration to define a &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; and request additional data with its own request from a device ==&lt;br /&gt;
&lt;br /&gt;
The normal automatic HTTP request that is done repeatedly after the defined interval has elapsed works well in cases where all required readings can be requested in one common HTTP request. If however a device needs individual requests with different URLs or different POST data for each value, then another method is necessary. &lt;br /&gt;
For such cases a &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; option can be defined and the user can either issue FHEM &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; commands each time he needs the reading or the user can set an attribute to request the reading automatically together with the normal iteration.&lt;br /&gt;
For each &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; option attributes define an individual URL, optional headers, and post data as well as individual regular expressions and formatting options. &lt;br /&gt;
&lt;br /&gt;
When a get option is defined by attributes, the module allows querying additional values from the device that require individual HTTP-Requests or special parameters to be sent&lt;br /&gt;
&lt;br /&gt;
Extension to the above example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM get01Name MyGetValue &amp;lt;br&amp;gt;&lt;br /&gt;
attr PM get01URL http://MyPoolManager/cgi-bin/directory/webgui.fcgi?special=1?sid=$sid &amp;lt;br&amp;gt;&lt;br /&gt;
attr PM getHeader1 Content-Type: application/json &amp;lt;br&amp;gt;&lt;br /&gt;
attr PM get01Data {&amp;quot;get&amp;quot; :{&amp;quot;30.1234.value&amp;quot;}} &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example defines a get option with the name MyGetValue.&lt;br /&gt;
By issuing &amp;lt;code&amp;gt;get PM MyGetValue&amp;lt;/code&amp;gt; in FHEM, the defined HTTP request is sent to the device.&lt;br /&gt;
The HTTP response is then parsed using the same readingXXName and readingXXRegex attributes as above so&lt;br /&gt;
additional pairs will probably be needed there for additional values.&lt;br /&gt;
&lt;br /&gt;
if you prefer to define the parsing and formatting of readings individually per get command, you can use &lt;br /&gt;
attributes like get01Regex, get01XPath, get01Format, get01OMap and so on just like for reading01...&lt;br /&gt;
&lt;br /&gt;
You can also include parameters / values that are passed to the get command in the request just like for set commands.&lt;br /&gt;
The placeholder $val will be replaced with the value given to the get command or you can specify your own replacement as described above.&lt;br /&gt;
&lt;br /&gt;
If the new get parameter should also be queried regularly, you can define the following optional attributes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM get01Poll 1&lt;br /&gt;
attr PM get01PollDelay 300&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first attribute includes this reading in the automatic update cycle and the second defines an alternative lower update frequency. When the interval defined initially in the define is over and the normal readings are read from the device, the update function will check for additional get parameters that should be included in the update cycle.&lt;br /&gt;
&lt;br /&gt;
If a PollDelay is specified for a get parameter, the update function also checks if the time passed since it has last read this value is more than the given PollDelay. If not, this reading is skipped and it will be rechecked in the next cycle when interval is over again. So the effective PollDelay will always be a multiple of the interval specified in the initial define.&lt;br /&gt;
&lt;br /&gt;
Please note that each defined get command that is included in the regular update cycle will create its own HTTP request. So if you want to extract several values from the same request, it is much more efficient to do this by defining readingXXName and readingXXRegex, XPath or JSON attributes and to specify an interval and a URL in the define of the HTTPMOD device. &lt;br /&gt;
&lt;br /&gt;
Example for a Siemens webserver provided by Lanhydrock:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define ozw672 HTTPMOD https://192.168.178.8/api/auth/login.json?user=test&amp;amp;pwd=test 300&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get1Name tempAussen&lt;br /&gt;
attr ozw672 get1URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1960&lt;br /&gt;
attr ozw672 get1Poll 1&lt;br /&gt;
attr ozw672 get1PollDelay 1800&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get2Name tempAussenGemischt&lt;br /&gt;
attr ozw672 get2URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1964&lt;br /&gt;
attr ozw672 get2Poll 1&lt;br /&gt;
attr ozw672 get2PollDelay 1800&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get3Name tempTWW&lt;br /&gt;
attr ozw672 get3URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1996&lt;br /&gt;
attr ozw672 get3Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get4Name tempKesselSoll&lt;br /&gt;
attr ozw672 get4URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1910&lt;br /&gt;
attr ozw672 get4Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get5Name tempKesselRuecklauf&lt;br /&gt;
attr ozw672 get5URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1915&lt;br /&gt;
attr ozw672 get5Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get6Name tempKesselRuecklaufSoll&lt;br /&gt;
attr ozw672 get6URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1916&lt;br /&gt;
attr ozw672 get6Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get7Name anzahlStartsBrenner&lt;br /&gt;
attr ozw672 get7URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1927&lt;br /&gt;
attr ozw672 get7PollDelay 1800&lt;br /&gt;
attr ozw672 get7Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get8Name statusKessel&lt;br /&gt;
attr ozw672 get8URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1898&lt;br /&gt;
attr ozw672 get8Poll 1&lt;br /&gt;
attr ozw672 get8Regex Value&amp;quot;: &amp;quot;([a-zA-Zü ]*)&amp;quot;&lt;br /&gt;
attr ozw672 get8OMap Aus:0, Nachlauf aktiv:5, Freigegeben für TWW:10, Freigegeben für HK:20, In Teillastbetrieb für TWW:40, In Teillastbetrieb für HK:50, In Betrieb für Trinkwasser:90, In Betrieb für Heizkreis:100&lt;br /&gt;
&lt;br /&gt;
attr ozw672 getRegex Value&amp;quot;: &amp;quot;[ ]*([-.0-9]*)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
attr ozw672 reAuthRegex .*session not valid.*&lt;br /&gt;
attr ozw672 sid1IDRegex .*&amp;quot;(.*-.*-.*-[0-9a-z]*).*&lt;br /&gt;
attr ozw672 sid1URL https://192.168.178.8/api/auth/login.json?user=test&amp;amp;pwd=test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== All attributes ==&lt;br /&gt;
;reading[0-9]+Name&lt;br /&gt;
:the name of a reading to extract with the corresponding readingRegex, readingJSON, readingXPath or readingXPath-Strict&lt;br /&gt;
:Please note that the old syntax &amp;lt;b&amp;gt;readingsName.*&amp;lt;/b&amp;gt; does not work with all features of HTTPMOD and should be avoided. It might go away in a future version of HTTPMOD.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]+Name&lt;br /&gt;
:Name of a get or set command&lt;br /&gt;
:If the HTTP response that is received after the command is parsed with an individual parse option then this name is also used as a reading name. Please note that no individual parsing needs to be defined for a get or set. If no regex, XPath or JSON is specified for the command, then HTTPMOD will try to parse the response using all the defined readingRegex, reading XPath or readingJSON attributes.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+Regex&lt;br /&gt;
:If this attribute is specified, the Regex defined here is used to extract the value from the HTTP Response and assign it to a Reading with the name defined in the (get|set|reading)[0-9]+Name attribute.&lt;br /&gt;
:If this attribute is not specified for an individual Reading or get or set but without the numbers in the middle, e.g. as getRegex or readingRegex, then it applies to all the other readings / get / set commands where no specific Regex is defined.&amp;lt;br&amp;gt;&lt;br /&gt;
:The value to extract should be in a capture group / sub expression e.g. ([\d\.]+) in the above example. Multiple capture groups will create multiple readings (see explanation above)&lt;br /&gt;
:Using this attribute for a set command (setXXRegex) only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
:Please note that the old syntax &amp;lt;code&amp;gt;readingsRegex.*&amp;lt;/code&amp;gt; does not work with all features of HTTPMOD and should be avoided. It might go away in a future version of HTTPMOD.&lt;br /&gt;
:If for get or set commands neither a generic Regex attribute without numbers nor a specific (get|set)[0-9]+Regex attribute is specified and also no XPath or JSON parsing specification is given for the get or set command, then HTTPMOD tries to use the parsing definitions for general readings defined in reading[0-9]+Name, reading[0-9]+Regex or XPath or JSON attributes and assigns the Readings that match here.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+RegOpt&lt;br /&gt;
:Lets the user specify regular expression modifiers. For example if the same regular expression should be matched as often as possible in the HTTP response, then you can specify RegOpt g which will case the matching to be done as /regex/g&lt;br /&gt;
:The results will be trated the same way as multiple capture groups so the reading name will be extended with -number. &lt;br /&gt;
:For other possible regular expression modifiers see http://perldoc.perl.org/perlre.html#Modifiers&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+XPath&lt;br /&gt;
:defines an xpath to one or more values when parsing HTML data (see examples above)&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;get|set|reading[0-9]+XPath-Strict&lt;br /&gt;
:defines an xpath to one or more values when parsing XML data (see examples above)&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+AutoNumLen&lt;br /&gt;
:In cases where a regular expression or an XPath results in multiple results and these results are stored in a common reading name with extension -number, then you can modify the format of this number to have a fixed length with leading zeros. AutoNumLen 3 for example will lead to reading names ending with -001 -002 and so on.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+AlwaysNum&lt;br /&gt;
:if set to 1 this attributes forces reading names to end with a -1, -01 (depending on the above described AutoNumLen) even if just one value is parsed.&lt;br /&gt;
&lt;br /&gt;
;get|set|reading[0-9]+JSON&lt;br /&gt;
:defines a path to the JSON object wanted by concatenating the object names. See the above example.&lt;br /&gt;
:If you don&#039;t know the paths, then start by using extractAllJSON and the use the names of the readings as values for the JSON attribute.&amp;lt;br&amp;gt;&lt;br /&gt;
:Please don&#039;t forget to also specify a name for a reading, get or set. &lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]*RecombineExpr&lt;br /&gt;
:defines an expression that is used in an eval to compute one reading value out of the list of matches.&lt;br /&gt;
:This is supposed to be used for regexes or xpath specifications that produce multiple results if only one result that combines them is wanted. The list of matches will be in the variable @matchlist.&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;get[0-9]*CheckAllReadings&lt;br /&gt;
:this attribute modifies the behavior of HTTPMOD when the HTTP Response of a get command is parsed. &amp;lt;br&amp;gt;&lt;br /&gt;
:If this attribute is set to 1, then additionally to the matching of the corresponding get specific regex (get[0-9]*Regex), XPath or JSON attribute also all the reading names and parse definitions defined in Reading[0-9]+Name and Reading[0-9]+Regex, XPath or JSON attributes are checked and if they match, the coresponding Readings are assigned as well.&lt;br /&gt;
:Please note that this does not mean that get01CheckAllReadings will cause a get02Regex to be used. Only the corresponding get01Regex will be used but additionally all the readingXYRegex attributes.&lt;br /&gt;
:This is automatically done if a get or set command is defined without its own parse attributes.&lt;br /&gt;
&lt;br /&gt;
;(get|reading)[0-9]*OExpr&lt;br /&gt;
:defines an optional expression that is used in an eval to compute / format a readings value after parsing an HTTP response&lt;br /&gt;
:The raw value from the parsing will be in the variable $val.&lt;br /&gt;
:If specified as readingOExpr then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*Expr.&lt;br /&gt;
:Please note that the old syntax &amp;lt;b&amp;gt;readingsExpr.*&amp;lt;/b&amp;gt; does not work with all features of HTTPMOD and should be avoided. It might go away in a future version of HTTPMOD.&lt;br /&gt;
&lt;br /&gt;
;(get|reading)[0-9]*Expr&lt;br /&gt;
:This is the old syntax for (get|reading)[0-9]*OExpr. It should be replaced by (get|reading)[0-9]*OExpr. The set command upgradeAttributes which becomes visible when the attribute enableControlSet is set to 1, can do this renaming automatically.&lt;br /&gt;
&lt;br /&gt;
;(get|reading)[0-9]*OMap&lt;br /&gt;
:Map that defines a mapping from raw value parsed to visible values like &amp;quot;0:mittig, 1:oberhalb, 2:unterhalb&amp;quot;.&lt;br /&gt;
:If specified as readingOMap then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*Map.&amp;lt;br&amp;gt;&lt;br /&gt;
:The individual options in a map are separated by a komma and an optional space. Spaces are allowed to appear in a visible value however kommas are not possible.&lt;br /&gt;
&lt;br /&gt;
;(get|reading)[0-9]*Map&lt;br /&gt;
:This is the old syntax for (get|reading)[0-9]*OMap. It should be replaced by (get|reading)[0-9]*OMap. The set command upgradeAttributes which becomes visible when the attribute enableControlSet is set to 1, can do this renaming automatically.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]*Format&lt;br /&gt;
:Defines a format string that will be used in sprintf to format a reading value.&lt;br /&gt;
:If specified without the numbers in the middle e.g. as readingFormat then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*Format.&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]*Decode&lt;br /&gt;
:defines an encoding to be used in a call to the perl function decode to convert the raw data string read from the device to a reading. &lt;br /&gt;
:This can be used if the device delivers strings in an encoding like cp850 instead of utf8.&lt;br /&gt;
:If your reading values contain Umlauts and they are shown as strange looking icons then you probably need to use this feature.&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]*Encode&lt;br /&gt;
:defines an encoding to be used in a call to the perl function encode to convert the raw data string read from the device to a reading. &lt;br /&gt;
:This can be used if the device delivers strings in an encoding like cp850 and after decoding it you want to reencode it to e.g. utf8.&lt;br /&gt;
:If your reading values contain Umlauts and they are shown as strange looking icons then you probably need to use this feature.&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*URL&lt;br /&gt;
:URL to be requested for the set or get command. If this option is missing, the URL specified during define will be used.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*Data&lt;br /&gt;
:Data to be sent to the device as POST data when the get or set command is executed. if this attribute is not specified, an HTTP GET method will be used instead of an HTTP POST&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*NoData&lt;br /&gt;
:can be used to override a more generic attribute that specifies POST data for all get or set commands. With NoData no data is sent and therefor the request will be an HTTP GET.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*Header.*&lt;br /&gt;
:HTTP Headers to be sent to the device when the set is executed&lt;br /&gt;
&lt;br /&gt;
;requestHeader.*&lt;br /&gt;
:Define an optional additional HTTP Header to set in the HTTP request of the main loop&lt;br /&gt;
&lt;br /&gt;
;requestData&lt;br /&gt;
:optional POST Data to be sent in the request of the main loop. If not defined, it will be an HTTP GET request as defined in HttpUtils which is used by this module&lt;br /&gt;
&lt;br /&gt;
;get[0-9]+Poll&lt;br /&gt;
:if set to 1 the get is executed automatically during the normal update cycle (after the interval provided in the define command has elapsed)&lt;br /&gt;
&lt;br /&gt;
;get[0-9]+PollDelay&lt;br /&gt;
:if the value should not be read in each iteration (after the interval given to the define command), then a minimum delay can be specified with this attribute. This has only an effect if the above Poll attribute has also been set. Every time the update function is called, it checks if since this get has been read the last time, the defined delay has elapsed. If not, then it is skipped this time.&lt;br /&gt;
:PollDelay can be specified as seconds or as x[0-9]+ which means a multiple of the interval in the define command.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*TextArg&lt;br /&gt;
:For a get command this defines that the command accepts a text value after the option name. By default a get command doesn&#039;t accept optional values after the command name. &lt;br /&gt;
:If TextArg is specified and a value is passed after the get name then this value can then be used in a request URL, header or data as replacement for $val or in a user defined replacement that uses the internal &amp;quot;value&amp;quot; ($hash-&amp;gt;{value}).&lt;br /&gt;
:If used for a set command then it defines that the value to be set doesn&#039;t require any validation / conversion. &lt;br /&gt;
:The raw value is passed on as text to the device. By default a set command expects a numerical value or a text value that is converted to a numeric value using a map.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Min&lt;br /&gt;
:Minimum value for input validation. &lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Max&lt;br /&gt;
:Maximum value for input validation. &lt;br /&gt;
&lt;br /&gt;
;set[0-9]+IExpr&lt;br /&gt;
:Perl Expression to compute the raw value to be sent to the device from the input value passed to the set.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Expr&lt;br /&gt;
:This is the old syntax for (get|reading)[0-9]*IExpr. It should be replaced by (get|reading)[0-9]*IExpr. The set command upgradeAttributes which becomes visible when the attribute enableControlSet is set to 1, can do this renaming automatically.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+IMap&lt;br /&gt;
:Map that defines a mapping from raw to input values like &amp;quot;0:mittig, 1:oberhalb, 2:unterhalb&amp;quot;. This attribute atomatically creates a hint for FHEMWEB so the user can choose one of the input values.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Map&lt;br /&gt;
:This is the old syntax for (get|reading)[0-9]*IMap. It should be replaced by (get|reading)[0-9]*IMap. The set command upgradeAttributes which becomes visible when the attribute enableControlSet is set to 1, can do this renaming automatically.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Hint&lt;br /&gt;
:Explicit hint for fhemWEB that will be returned when set ? is seen. Can be used to get a slider or a list of values to choose from.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]*NoArg&lt;br /&gt;
:Defines that this set option doesn&#039;t require arguments. It allows sets like &amp;quot;on&amp;quot; or &amp;quot;off&amp;quot; without further values.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]*ParseResponse&lt;br /&gt;
:defines that the HTTP response to the set will be parsed as if it was the response to a get command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*URLExpr&lt;br /&gt;
:Defines a Perl expression to specify the HTTP Headers for this request. This overwrites any other header specification and should be used carefully only if needed. The original Header is availabe as $old. Typically this feature is not needed and it might go away in future versions of HTTPMOD. Please use the &amp;quot;replacement&amp;quot; attributes if you want to pass additional variable data to a web service. &lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*DatExpr&lt;br /&gt;
:Defines a Perl expression to specify the HTTP Post data for this request. This overwrites any other post data specification and should be used carefully only if needed. The original Data is availabe as $old. Typically this feature is not needed and it might go away in future versions of HTTPMOD. Please use the &amp;quot;replacement&amp;quot; attributes if you want to pass additional variable data to a web service. &lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*HdrExpr&lt;br /&gt;
:Defines a Perl expression to specify the URL for this request. This overwrites any other URL specification and should be used carefully only if needed. The original URL is availabe as $old. Typically this feature is not needed and it might go away in future versions of HTTPMOD. Please use the &amp;quot;replacement&amp;quot; attributes if you want to pass additional variable data to a web service.           &lt;br /&gt;
&lt;br /&gt;
;ReAuthRegex&lt;br /&gt;
:regular Expression to match an error page indicating that a session has expired and a new authentication for read access needs to be done. &lt;br /&gt;
:This attribute only makes sense if you need a forms based authentication for reading data and if you specify a multi step login procedure based on the sid.. attributes.&lt;br /&gt;
:This attribute is used for all requests. For set and get operations you can however specify individual reAuthRegexes with the (get|set)[0-9]*ReAuthRegex attributes.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*ReAuthRegex&lt;br /&gt;
:Regex that will detect when a session has expired during a set operation and a new login needs to be performed.&lt;br /&gt;
:It works like the global reAuthRegex but is used for set operations.&lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*URL&lt;br /&gt;
:different URLs or one common URL to be used for each step of an optional login procedure. &lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*IDRegex&lt;br /&gt;
:different Regexes per login procedure step or one common Regex for all steps to extract the session ID from the HTTP response&lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*Data.*&lt;br /&gt;
:data part for each step to be sent as POST data to the corresponding URL&lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*Header.*&lt;br /&gt;
:HTTP Headers to be sent to the URL for the corresponding step&lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*IgnoreRedirects&lt;br /&gt;
:Tells the HttpUtils to not follow HTTP Redirects for this Request. Might be needed for some devices that set a session cookie within a 303 Redirect.&lt;br /&gt;
&lt;br /&gt;
;clearSIdBeforeAuth&lt;br /&gt;
:will set the session id to &amp;quot;&amp;quot; before doing the authentication steps&lt;br /&gt;
&lt;br /&gt;
;authRetries&lt;br /&gt;
:number of retries for authentication procedure - defaults to 1&lt;br /&gt;
&lt;br /&gt;
;replacement[0-9]*Regex&lt;br /&gt;
:Defines a replacement to be applied to an HTTP request header, data or URL before it is sent. This allows any part of the request to be modified based on a reading, an internal or an expression.&lt;br /&gt;
:The regex defines which part of a header, data or URL should be replaced. The replacement is defined with the following attributes:&lt;br /&gt;
&lt;br /&gt;
;replacement[0-9]*Mode&lt;br /&gt;
:Defines how the replacement should be done and what replacementValue means. Valid options are text, reading, internal and expression.&lt;br /&gt;
&lt;br /&gt;
;replacement[0-9]*Value&lt;br /&gt;
:Defines the replacement. If the corresponding replacementMode is &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt;, then value is a static text that is used as the replacement.&lt;br /&gt;
:If replacementMode is &amp;lt;code&amp;gt;reading&amp;lt;/code&amp;gt; then Value can be the name of a reading of this device or it can be a reading of a different device referred to by devicename:reading.&lt;br /&gt;
:If replacementMode is &amp;lt;code&amp;gt;internal&amp;lt;/code&amp;gt; the Value can be the name of an internal of this device or it can be an internal of a different device referred to by devicename:internal.&lt;br /&gt;
:If replacementMode is &amp;lt;code&amp;gt;expression&amp;lt;/code&amp;gt; the the Value is treated as a Perl expression that computes the replacement value. The expression can use $1, $2 and so on to refer to capture groups of the corresponding regex that is matched against the original URL, header or post data.&lt;br /&gt;
:If replacementMode is &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; then the module will use a value from a key / value pair that is stored in an obfuscated form in the file system with the set storeKeyValue command. This might be useful for storing passwords.&lt;br /&gt;
&lt;br /&gt;
;[gs]et[0-9]*Replacement[0-9]*Value&lt;br /&gt;
:This attribute can be used to override the replacement value for a specific get or set.&lt;br /&gt;
&lt;br /&gt;
;get|reading[0-9]*MaxAge&lt;br /&gt;
:Defines how long a reading is valid before it is automatically overwritten with a replacement when the read function is called the next time.&lt;br /&gt;
&lt;br /&gt;
;get|reading[0-9]*MaxAgeReplacement&lt;br /&gt;
:specifies the replacement for MaxAge - either as a static text or as a perl expression.&lt;br /&gt;
&lt;br /&gt;
;get|reading[0-9]*MaxAgeReplacementMode&lt;br /&gt;
:specifies how the replacement is interpreted: can be text, expression and delete.&lt;br /&gt;
&lt;br /&gt;
;get|reading[0-9]*DeleteIfUnmatched&lt;br /&gt;
:If set to 1 this attribute causes certain readings to be deleted when the parsing of the website does not match the specified reading. Internally HTTPMOD remembers which kind of operation created a reading (update, Get01, Get02 and so on). Specified readings will only be deleted if the same operation does not parse this reading again. This is especially useful for parsing that creates several matches / readings and the number of matches can vary from request to request. For example if reading01Regex creates 4 readings in one update cycle and in the next cycle it only matches two times then the readings containing the remaining values from the last round will be deleted.&lt;br /&gt;
:Please note that this mechanism will not work in all cases after a restart. Especially when a get definition does not contain its own parsing definition but ExtractAllJSON or relies on HTTPMOD to use all defined reading.* attributes to parse the responsee to a get command, old readings might not be deleted after a restart of fhem.&lt;br /&gt;
;get|reading[0-9]*DeleteOnError&lt;br /&gt;
:If set to 1 this attribute causes certain readings to be deleted when the website can not be reached and the HTTP request returns an error. Internally HTTPMOD remembers which kind of operation created a reading (update, Get01, Get02 and so on). Specified readings will only be deleted if the same operation returns an error.&lt;br /&gt;
The same restrictions as for DeleteIfUnmatched apply regarding a fhem restart.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;httpVersion&lt;br /&gt;
:defines the HTTP-Version to be sent to the server. This defaults to 1.0.&lt;br /&gt;
&lt;br /&gt;
;sslVersion&lt;br /&gt;
:defines the SSL Version for the negotiation with the server. The attribute is evaluated by HttpUtils. If it is not specified, HttpUtils assumes SSLv23:!SSLv3:!SSLv2&lt;br /&gt;
&lt;br /&gt;
;sslArgs&lt;br /&gt;
:defines a list that is converted to a key / value hash and gets passed to HttpUtils. To avoid certificate validation for broken servers you can for example specify &lt;br /&gt;
:&amp;lt;code&amp;gt;attr myDevice sslArgs SSL_verify_mode,SSL_VERIFY_NONE&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;alignTime&lt;br /&gt;
:Aligns each periodic read request for the defined interval to this base time. This is typcally something like 00:00 (see the FHEM at command)&lt;br /&gt;
&lt;br /&gt;
;noShutdown&lt;br /&gt;
:pass the noshutdown flag to HTTPUtils for webservers that need it (some embedded webservers only deliver empty pages otherwise)&lt;br /&gt;
&lt;br /&gt;
;disable&lt;br /&gt;
:stop doing automatic HTTP requests while this attribute is set to 1&lt;br /&gt;
&lt;br /&gt;
;enableControlSet&lt;br /&gt;
:enables the built in set commands interval, stop, start, reread, upgradeAttributes, storeKeyValue.&lt;br /&gt;
&lt;br /&gt;
;enableCookies&lt;br /&gt;
:enables the built in cookie handling if set to 1. With cookie handling each HTTPMOD device will remember cookies that the server sets and send them back to the server in the following requests. &lt;br /&gt;
:This simplifies session magamenet in cases where the server uses a session ID in a cookie. In such cases enabling cookies should be sufficient and no sidRegex and no manual definition of a cookie header should be necessary.&lt;br /&gt;
&lt;br /&gt;
;showMatched&lt;br /&gt;
:if set to 1 then HTTPMOD will create a reading with the name MATCHED_READINGS that contains the names of all readings that could be matched in the last request as well as UNMATCHED_READINGS and LAST_REQUEST.&lt;br /&gt;
&lt;br /&gt;
;showError&lt;br /&gt;
:if set to 1 then HTTPMOD will create a reading and event with the Name LAST_ERROR that contains the error message of the last error returned from HttpUtils. &lt;br /&gt;
&lt;br /&gt;
;removeBuf&lt;br /&gt;
:if set to 1 then HTTPMOD removes the internal named buf when a HTTP-response has been received. &lt;br /&gt;
:$hash-&amp;gt;{buf} is used internally be Fhem httpUtils and in some use cases it is desireable to remove this internal after reception &lt;br /&gt;
:because it contains a very long response which looks ugly in Fhemweb.&lt;br /&gt;
&lt;br /&gt;
;timeout&lt;br /&gt;
:time in seconds to wait for an answer. Default value is 2&lt;br /&gt;
&lt;br /&gt;
;queueDelay&lt;br /&gt;
:HTTP Requests will be sent from a queue in order to avoid blocking when several Requests have to be sent in sequence. This attribute defines the delay between calls to the function that handles the send queue. It defaults to one second.&lt;br /&gt;
&lt;br /&gt;
;queueMax&lt;br /&gt;
:Defines the maximum size of the send queue. If it is reached then further HTTP Requests will be dropped and not be added to the queue&lt;br /&gt;
&lt;br /&gt;
;minSendDelay&lt;br /&gt;
:Defines the minimum time between two HTTP Requests.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* Beispiel: [[Wetter_und_Wettervorhersagen#Wetter_von_Weather_Underground|Wetter von WeatherUnderground auslesen]]&lt;br /&gt;
* Beispiel: [[Pollenflug]]&lt;br /&gt;
* Beispiel: [[HTTPMOD Beispielkonfiguration zur Anbindung einer Daikin Klimaanlage mit WLAN-Modul]]&lt;br /&gt;
* Beispiel: [[Go-eCharger|Auslesen der Information der Wallbox go-eCharger]]&lt;br /&gt;
* Beispiel: [[Sonnenspeicher|Einbindung des Speichersystems von sonnen (https://sonnen.de/stromspeicher/)]]&lt;br /&gt;
* {{Link2Forum|Topic=17804|LinkText=Thread}} in FHEM Forum that discusses the first version of this module &lt;br /&gt;
* {{Link2Forum|Topic=29471|LinkText=Thread}} in FHEM Forum that discusses the second major version of this module &lt;br /&gt;
* {{Link2Forum|Topic=45176|LinkText=Thread}} in FHEM Forum that discusses the third major version of this module &lt;br /&gt;
* [http://perldoc.perl.org/perlretut.html Introduction to regular expressions]&lt;br /&gt;
* [http://portswigger.net/burp/ BurpSuite]: Tool (local proxy) to help analyze http traffic&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:IP Components]]&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Sonnenspeicher&amp;diff=27839</id>
		<title>Sonnenspeicher</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Sonnenspeicher&amp;diff=27839"/>
		<updated>2018-09-12T20:40:10Z</updated>

		<summary type="html">&lt;p&gt;C2j2: Einbindung des Speichersystems von sonnen per HTTPMOD&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hinweise zur schnellen Einbindung des Speichersystems von sonnen (https://sonnen.de/stromspeicher/) per HTTPMOD ==&lt;br /&gt;
&lt;br /&gt;
Im Kürze:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define sonnenbatterie HTTPMOD http://x.x.x.x:8080/api/v1/status 60&lt;br /&gt;
attr sonnenbatterie extractAllJSON 1&lt;br /&gt;
attr sonnenbatterie stateFormat {sprintf(&amp;quot;PV %d W -&amp;gt; Haushalt %d W + Grid %d W + %d W, SOC %d%%&amp;quot;, \&lt;br /&gt;
ReadingsVal($name,&amp;quot;Production_W&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;Consumption_W&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;GridFeedIn_W&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;Pac_total_W&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;RSOC&amp;quot;,&amp;quot;-1&amp;quot;)\&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Leere_Seite_2&amp;diff=27838</id>
		<title>Leere Seite 2</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Leere_Seite_2&amp;diff=27838"/>
		<updated>2018-09-12T20:21:27Z</updated>

		<summary type="html">&lt;p&gt;C2j2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hinweise zur schnellen Einbindung von go-eCharger (https://go-e.co/de/) per HTTPMOD ==&lt;br /&gt;
&lt;br /&gt;
Voraussetzung ist, dass die HTTP-API aktiviert ist:&lt;br /&gt;
* Smartphone mit e-goCharger WLAN verbinden&lt;br /&gt;
* in &amp;quot;Cloud&amp;quot;, &amp;quot;erweiterte Einstellungen&amp;quot; das HTTP-Protokoll aktivieren&lt;br /&gt;
* &amp;quot;Neustart&amp;quot; auswählen (ohne diesen war bei mir die Box nicht zu erreichen)&lt;br /&gt;
* fertig, Smartphone kann wieder ins normale WLAN&lt;br /&gt;
&lt;br /&gt;
Dann in FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define go_eCharger HTTPMOD http://go-eCharger/status 30&lt;br /&gt;
attr go_eCharger extractAllJSON 1&lt;br /&gt;
attr go_eCharger stateFormat {sprintf(&amp;quot;%s: %s Current %d A, ETO=%d kWh&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==1?&amp;quot;ready, waiting for car&amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==2?&amp;quot;car loading&amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==3?&amp;quot;waiting for car&amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==4?&amp;quot;charge finished, but connected&amp;quot;:&amp;quot;unknown&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==1?&amp;quot;error RCCB: &amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==3?&amp;quot;error PHASE: &amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==8?&amp;quot;error NO_GROUND: &amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==10?&amp;quot;error INTERNAL: &amp;quot;:&amp;quot;&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;amp&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;eto&amp;quot;,0)/10,\&lt;br /&gt;
&amp;quot;&amp;quot;\&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das dürfte so das Wichtigste sein, um die Werte auszulesen.&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=HTTPMOD&amp;diff=27837</id>
		<title>HTTPMOD</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=HTTPMOD&amp;diff=27837"/>
		<updated>2018-09-12T20:17:59Z</updated>

		<summary type="html">&lt;p&gt;C2j2: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Extract information from devices with an HTTP interface (or, more generic, from any URL) or send information to such devices &lt;br /&gt;
|ModType=d&lt;br /&gt;
|ModCmdRef=HTTPMOD&lt;br /&gt;
|ModForumArea=Sonstiges&lt;br /&gt;
|ModTechName=98_HTTPMOD.pm&lt;br /&gt;
|ModOwner=StefanStrobel ({{Link2FU|3960|Forum}} / [[Benutzer:StefanStrobel|Wiki]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
HTTPMOD provides a generic way to retrieve information from devices with an HTTP Interface and store them in Readings or send information to such devices. It queries a given URL with Headers and data defined by attributes. &lt;br /&gt;
&lt;br /&gt;
From the HTTP response it extracts readings named in attributes using Regexes, JSON or XPath parsing also defined by attributes.&lt;br /&gt;
&lt;br /&gt;
In an advanced [[Konfiguration|configuration]] the module can also send information to devices. To do this, a generic &amp;lt;code&amp;gt;set&amp;lt;/code&amp;gt; option can be configured using attributes. &lt;br /&gt;
&lt;br /&gt;
== Availability == &lt;br /&gt;
The module is part of the regular FHEM distribution.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
This module uses the non blocking HTTP function &amp;lt;code&amp;gt;HttpUtils_NonblockingGet&amp;lt;/code&amp;gt; provided by FHEM&#039;s [[HttpUtils]] in a new version published in December 2013.&lt;br /&gt;
If not already installed in your environment, please [[update]] FHEM or install it manually using appropriate commands from your environment.&lt;br /&gt;
Please also note that FHEM HttpUtils need the global attribute dnsServer to be set in order to work really non blocking even when dns requests can not be answered.&lt;br /&gt;
&lt;br /&gt;
== Define ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define &amp;lt;name&amp;gt; HTTPMOD &amp;lt;URL&amp;gt; &amp;lt;Interval&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The module connects to the given &amp;lt;code&amp;gt;URL&amp;lt;/code&amp;gt; every &amp;lt;code&amp;gt;Interval&amp;lt;/code&amp;gt; seconds, sends optional headers and data and then parses the response with regular expressions, xpath or json to set readings.&lt;br /&gt;
&lt;br /&gt;
URL can be &amp;quot;none&amp;quot; and Interval can be 0 if you prefer to only query data with a get command and not in a defined interval.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define PM HTTPMOD http://MyPoolManager/cgi-bin/webgui.fcgi 60&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Set-Commands ==&lt;br /&gt;
can be defined using attributes, see advanced configuration&lt;br /&gt;
&lt;br /&gt;
If you set the attribute enableControlSet to 1, the following additional built in set commands are available:&lt;br /&gt;
;interval&lt;br /&gt;
:set new interval time in seconds and restart the timer&lt;br /&gt;
;reread&lt;br /&gt;
:request the defined URL and try to parse it just like the automatic update would do it every Interval seconds without modifying the running timer.&lt;br /&gt;
;stop&lt;br /&gt;
:stop interval timer.&lt;br /&gt;
;start&lt;br /&gt;
:restart interval timer to call GetUpdate after interval seconds&lt;br /&gt;
;upgradeAttributes&lt;br /&gt;
:convert outdated attributes for older HTTPMOD-Versions that are still defined for this device from the old syntax to the new one.&lt;br /&gt;
:attributes with the description &amp;quot;this attribute should not be used anymore&amp;quot; or similar will be translated to the new syntax, e.g. readingsName1 to reading01Name.&lt;br /&gt;
;storeKeyValue&lt;br /&gt;
:stores a key value pair in an obfuscated form in the file system. Such values can then be used in replacements where the mode is &amp;quot;key&amp;quot; e.g. to avoid storing passwords in the configuration in clear text&lt;br /&gt;
&lt;br /&gt;
== Get-Commands ==&lt;br /&gt;
can be defined using attributes, see advanced configuration&lt;br /&gt;
&lt;br /&gt;
== simple Attributes ==&lt;br /&gt;
;enableControlSet&lt;br /&gt;
:enables the built in set commands &#039;&#039;interval&#039;&#039;, &#039;&#039;stop&#039;&#039;, &#039;&#039;start&#039;&#039;, &#039;&#039;reread&#039;&#039;, &#039;&#039;upgradeAttributes&#039;&#039;, &#039;&#039;storeKeyValue&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
;enableCookies&lt;br /&gt;
:enables the cookie handling inside HTTPMOD. It is advisable to always set this attribute and allow HTTPMOD to track the state of cookies and set them for following HTTP-requests&lt;br /&gt;
&lt;br /&gt;
;enforceGoodReadingNames&lt;br /&gt;
:makes sure that HTTPMOD only creates readings that are allowd for Fhem (especially if reading names are dynamically created from JSON object names with extractAllJSON. It is advisable to always set this attribute.&lt;br /&gt;
&lt;br /&gt;
;handleRedirects&lt;br /&gt;
:enables the redirect handling inside HTTPMOD which should be used together with the cookie handling of HTTPMOD. HTTPMOD will then automatically follow redirects from a web server and keep track of cookies at the same time. It is advisable to always set this attribute.&lt;br /&gt;
&lt;br /&gt;
;requestHeader.* &lt;br /&gt;
:Define an additional HTTP Header to set in the HTTP request&lt;br /&gt;
&lt;br /&gt;
;requestData&lt;br /&gt;
:POST Data to be sent in the request. If not defined, it will be a GET request as defined in HttpUtils used by this module&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+(-[0-9]+)?Name&lt;br /&gt;
:the name of a reading to extract with the corresponding readingRegex&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?OExpr&lt;br /&gt;
:defines an expression that is used in an eval to compute the readings value. The raw value will be in the variable $val.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?OMap&lt;br /&gt;
:Output Map. Defines a mapping from raw to visible values like &amp;quot;0:mittig, 1:oberhalb, 2:unterhalb&amp;quot;. If specified as readingOMap then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*OMap.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?Format&lt;br /&gt;
:Defines a format string that will be used in sprintf to format a reading value. If specified as readingFormat then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*Format.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?Decode&lt;br /&gt;
:defines an encoding to be used in a call to the perl function decode to convert the raw data string read from the device to a reading. This can be used if the device delivers strings in an encoding like cp850 instead of utf8.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]*(-[0-9]+)?Encode&lt;br /&gt;
:defines an encoding to be used in a call to the perl function encode to convert the raw data string read from the device to a reading. This can be used if the device delivers strings in an encoding like cp850 and after decoding it you want to reencode it to e.g. utf8.&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+Regex&lt;br /&gt;
:defines the regex to be used for extracting the reading. The value to extract should be in a capture group / sub expression &lt;br /&gt;
:e.g. ([\d\.]+) in the above example. Multiple capture groups will create multiple readings (see explanation above)&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+XPath&lt;br /&gt;
:defines an xpath to one or more readings when parsing HTML data (see examples below)&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+XPath-Strict&lt;br /&gt;
:defines an xpath to one or more readings when parsing XML data (see examples below)&lt;br /&gt;
&lt;br /&gt;
;reading[0-9]+JSON&lt;br /&gt;
:defines a path to the JSON object wanted by concatenating the object names with an underscore as delimiter (see the example below)&lt;br /&gt;
&lt;br /&gt;
;noShutdown&lt;br /&gt;
:pass the noshutdown flag to HTTPUtils for webservers that need it (some embedded webservers only deliver empty pages otherwise)&lt;br /&gt;
&lt;br /&gt;
;disable&lt;br /&gt;
:stop doing automatic HTTP requests while this attribute is set to 1&lt;br /&gt;
&lt;br /&gt;
;timeout&lt;br /&gt;
:time in seconds to wait for an answer. Default value is 2&lt;br /&gt;
&lt;br /&gt;
;do_not_notify&lt;br /&gt;
&lt;br /&gt;
;readingFnAttributes&lt;br /&gt;
&lt;br /&gt;
== Simple Configuration of HTTP Devices ==&lt;br /&gt;
If your device expects special HTTP-headers then specify them as &amp;lt;code&amp;gt;attr requestHeader1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;attr requestHeaderX&amp;lt;/code&amp;gt;.&lt;br /&gt;
If your Device expects an HTTP POST instead of HTTP GET then the POST-data can be specified as &amp;lt;code&amp;gt;attr requestData&amp;lt;/code&amp;gt;.&lt;br /&gt;
To get the readings, specify pairs of &amp;lt;code&amp;gt;attr readingXName&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;attr readingXRegex&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attr readingXXPath&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attr readingXXPath-Strict&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;attr readingXJSON&amp;lt;/code&amp;gt; to define which readings you want to extract from the HTTP response and how to extract them. (The old syntax &amp;lt;code&amp;gt;attr readingsNameX&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;attr readingsRegexX&amp;lt;/code&amp;gt; is still supported but the new one with &amp;lt;code&amp;gt;attr readingXName&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;attr readingXRegex&amp;lt;/code&amp;gt; should be preferred. The actual values to be extracted have to be sub expressions within () in the regex (see example below)&lt;br /&gt;
&lt;br /&gt;
=== Example for a PoolManager 5: ===&lt;br /&gt;
The PoolManager Web GUI can be queried with HTTP POST Requests like this one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
POST /cgi-bin/webgui.fcgi HTTP/1.1&lt;br /&gt;
Host: 192.168.70.90&lt;br /&gt;
Accept: */*&lt;br /&gt;
Content-Type: application/json;charset=UTF-8&lt;br /&gt;
Content-Length: 60&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;get&amp;quot; :[&amp;quot;34.4001.value&amp;quot; ,&amp;quot;34.4008.value&amp;quot; ,&amp;quot;34.4033.value&amp;quot;]}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting HTTP Response would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Content-type: application/json; charset=UTF-8&lt;br /&gt;
Expires: 0&lt;br /&gt;
Cache-Control: no-cache&lt;br /&gt;
Date: Sun, 12 Jan 2014 12:23:11 GMT&lt;br /&gt;
Server: lighttpd/1.4.26&lt;br /&gt;
Content-Length: 179&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;data&amp;quot;:	{&lt;br /&gt;
		&amp;quot;34.4001.value&amp;quot;:	&amp;quot;7.00&amp;quot;,&lt;br /&gt;
		&amp;quot;34.4008.value&amp;quot;:	&amp;quot;0.52&amp;quot;,&lt;br /&gt;
		&amp;quot;34.4033.value&amp;quot;:	&amp;quot;24.8&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;status&amp;quot;:	{&lt;br /&gt;
		&amp;quot;code&amp;quot;:	0&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;event&amp;quot;:	{&lt;br /&gt;
		&amp;quot;type&amp;quot;:	1,&lt;br /&gt;
		&amp;quot;data&amp;quot;:	&amp;quot;48.30000.0&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To configure HTTPMOD for a PoolManager one would first define a PoolManager device with e.g. the name PM, the URL and an interval of e.g. 60 seconds. &lt;br /&gt;
&lt;br /&gt;
Then the data to be sent in the request needs to be defined because in this example the device expects a POST request so the query is not contained in the URL but in the request data.&lt;br /&gt;
&lt;br /&gt;
Also as seen above the device expects special HTTP headers in the request so these headers also need to be defined as &amp;lt;code&amp;gt;attr PM requestHeader1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;attr PM requestHeader2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then the names of the readings to be extracted would be set with attributes&lt;br /&gt;
&lt;br /&gt;
Then for each reading value to be extracted a regular expression needs to be set that will match the value in question within ().&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define PM HTTPMOD http://MyPoolManager/cgi-bin/webgui.fcgi 60&lt;br /&gt;
&lt;br /&gt;
attr PM enableControlSet 1&lt;br /&gt;
attr PM enableCookies 1&lt;br /&gt;
attr PM enforceGoodReadingNames 1&lt;br /&gt;
attr PM handleRedirects 1&lt;br /&gt;
&lt;br /&gt;
attr PM reading01Name PH&lt;br /&gt;
attr PM reading01Regex 34.4001.value&amp;quot;:[ \t]+&amp;quot;([\d\.]+)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
attr PM reading02Name CL&lt;br /&gt;
attr PM reading02Regex 34.4008.value&amp;quot;:[ \t]+&amp;quot;([\d\.]+)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
attr PM reading03Name3TEMP&lt;br /&gt;
attr PM reading03Regex 34.4033.value&amp;quot;:[ \t]+&amp;quot;([\d\.]+)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
attr PM requestData {&amp;quot;get&amp;quot; :[&amp;quot;34.4001.value&amp;quot; ,&amp;quot;34.4008.value&amp;quot; ,&amp;quot;34.4033.value&amp;quot;, &amp;quot;14.16601.value&amp;quot;, &amp;quot;14.16602.value&amp;quot;]}&lt;br /&gt;
attr PM requestHeader1 Content-Type: application/json&lt;br /&gt;
attr PM requestHeader2 Accept: */*&lt;br /&gt;
attr PM stateFormat {sprintf(&amp;quot;%.1f Grad, PH %.1f, %.1f mg/l Chlor&amp;quot;, ReadingsVal($name,&amp;quot;TEMP&amp;quot;,0), ReadingsVal($name,&amp;quot;PH&amp;quot;,0), ReadingsVal($name,&amp;quot;CL&amp;quot;,0))}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example for AmbientMonitor ===&lt;br /&gt;
AmbientMonitor is a webbased visualisation for sensors connected to an Arduino device. Its web interface can also be queried with HTTMOD to grab the data into readings.&lt;br /&gt;
&lt;br /&gt;
This example was provided by locutus. The hardware configuration is an Arduino + Ethercard with ENC28J60 Controller + DHT22 Sensor and software can be downloaded from https://github.com/lucadentella/AmbientMonitor&lt;br /&gt;
&lt;br /&gt;
In this example an HTTP GET is sufficent, so no &amp;lt;code&amp;gt;requestData&amp;lt;/code&amp;gt; is needed. The device provides temperature and humidity readings in an HTTP response that looks like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.0 200 OK &lt;br /&gt;
Content-Type: text/html &lt;br /&gt;
&lt;br /&gt;
myCB({&#039;temperature&#039;:22.00,&#039;humidity&#039;:46.00})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the definition could be:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define AmbientMonitor HTTPMOD http://192.168.1.221/?callback=? 300&lt;br /&gt;
&lt;br /&gt;
attr AmbientMonitor enableControlSet 1&lt;br /&gt;
attr AmbientMonitor enableCookies 1&lt;br /&gt;
attr AmbientMonitor enforceGoodReadingNames 1&lt;br /&gt;
attr AmbientMonitor handleRedirects 1&lt;br /&gt;
&lt;br /&gt;
attr AmbientMonitor requestHeader Content-Type: application/json&lt;br /&gt;
attr AmbientMonitor reading1Name Temperatur&lt;br /&gt;
attr AmbientMonitor reading1Regex temperature&#039;:([\d\.]+)&lt;br /&gt;
attr AmbientMonitor reading2Name Feuchtigkeit&lt;br /&gt;
attr AmbientMonitor reading2Regex humidity&#039;:([\d\.]+)&lt;br /&gt;
attr AmbientMonitor stateFormat {sprintf(&amp;quot;Temperatur %.1f C, Feuchtigkeit %.1f %&amp;quot;, ReadingsVal($name,&amp;quot;Temperatur&amp;quot;,0), ReadingsVal($name,&amp;quot;Feuchtigkeit&amp;quot;,0))}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== formatting and manipulating values / readings ==&lt;br /&gt;
Values that are parsed from an HTTP response can be further treated or formatted with the following attributes:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?OExpr&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?OMap&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?Format&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?Decode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?Encode&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can all be specified for an individual reading, for all readings in one match (e.g. if a regular expression has several capture groups) or for all readings in a get command (defined by getXX) or for all readings in the main reading list (defined by readingXX):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading01Format %.1f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will format the reading with the name specified by the attribute reading01Name to be numerical with one digit after the decimal point.&lt;br /&gt;
If the attribute reading01Regex is used and contains several capture groups then the format will be applied to all readings parsed by this regex unless these readings have their own format specified by reading01-1Format, reading01-2Format and so on.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading01-2Format %.1f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be used in cases where a regular expression specified as reading01regex contains several capture groups or an xpath specified as reading01XPath creates several readings. &lt;br /&gt;
In this case reading01-2Format specifies the format to be applied to the second match.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
readingFormat %.1f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
applies to all readings defined by a reading-Attribute that have no more specific format.&lt;br /&gt;
&lt;br /&gt;
If you need to do some calculation on a raw value before it is used as a reading, you can define the attribute &amp;lt;code&amp;gt;readingOExpr&amp;lt;/code&amp;gt;.&lt;br /&gt;
It defines a Perl expression that is used in an eval to compute the readings value. The raw value will be in the variable $val.&lt;br /&gt;
&lt;br /&gt;
Example for an expression:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM reading03OExpr $val * 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Just like in the above example of the readingFormat attributes, readingOExpr and the other following attributes can be applied on several levels.&lt;br /&gt;
&lt;br /&gt;
To map a numerical value to a name, you can use the readingOMap attribute. &lt;br /&gt;
It defines a mapping from raw to visible values like &amp;quot;0:mittig, 1:oberhalb, 2:unterhalb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example for a map:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM reading02-3OMap 0:kalt, 1:warm, 2:sehr warm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To convert character sets, the module can first decode a string read from the device and then encode it again. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM getDecode UTF-8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This applies to all readings defined for Get-Commands.&lt;br /&gt;
&lt;br /&gt;
== Some help with Regular Expressions ==&lt;br /&gt;
{{Randnotiz|RNTyp=y|RNText=Starting with version &#039;&#039;2018-02-10&#039;&#039; the internal that holds the HTTP response is no longer called &#039;&#039;&#039;&#039;&#039;buf&#039;&#039;&#039;&#039;&#039; but rather &#039;&#039;&#039;&#039;&#039;httpbody&#039;&#039;&#039;&#039;&#039;, and it is only displayed when attribute &#039;&#039;&#039;&#039;&#039;showBody&#039;&#039;&#039;&#039;&#039; is set to &amp;quot;1&amp;quot;.}}&lt;br /&gt;
If HTTPMOD seems not to work and the FHEM Logfile contains a message like  &lt;br /&gt;
:&amp;lt;code&amp;gt;HTTPMOD: Response didn&#039;t match Reading ...&amp;lt;/code&amp;gt;&lt;br /&gt;
then you should check if the value you want to extract is read into the internal with the name buf. Internals are visible when you click on the defined HTTPMOD Device. buf is an internal variable that contains the HTTP Response read. If the value is there and you get the mentioned message then probably something is wrong with your regular expression. Please note that buf might contain special characters like newlines but they are not shown in fhemweb. If you are new to regular expressions then the introduction at http://perldoc.perl.org/perlretut.html might be helpful. &lt;br /&gt;
&lt;br /&gt;
For a typical HTTPMOD use case where you want to extract a number out of a HTTP-Response you can use something like &amp;lt;code&amp;gt;[\d\.]+&amp;lt;/code&amp;gt; to match the number itself. The expression matches the number characters (&amp;lt;code&amp;gt;\d&amp;lt;/code&amp;gt;) or a &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt; if one of these characters occurs at least once. &lt;br /&gt;
&lt;br /&gt;
To tell HTTPMOD that the number is what you want to use for the reading, you have to put the expression in between &amp;lt;code&amp;gt;()&amp;lt;/code&amp;gt;. A &amp;lt;code&amp;gt;([\d\.]+)&amp;lt;/code&amp;gt; alone would match the longest number in the HTTP Response which is very likely not the number you are looking for so you need to add something to the expression to give it a context and define how to find the number that you are looking for.&lt;br /&gt;
&lt;br /&gt;
If there is a title text before the number or a special text after the number you can put this in the regex. In one of the examples above &amp;lt;code&amp;gt;humidity&#039;:([\d\.]+)&amp;lt;/code&amp;gt; is looking for the number that immediately follows the text &amp;lt;code&amp;gt;humidity&#039;:&amp;lt;/code&amp;gt; without any blanks in between.&lt;br /&gt;
Be careful if the text you are getting from your device contains special characters like newline. You don&#039;t see such special characters in the fhem webinterface as contents of the internal buf but they might cause your regular expression to fail. &lt;br /&gt;
&lt;br /&gt;
If you have trouble defining a regular expression that matches a certain name, then many complicated characters and then a number, it might be helpful to use a negation in matching like &amp;lt;code&amp;gt;temp[^\d]+([\d\.]).*&amp;lt;/code&amp;gt;. In this examle &amp;lt;code&amp;gt;[^\d]+&amp;lt;/code&amp;gt; means any character that is not a numerical digit, more than once.&lt;br /&gt;
&lt;br /&gt;
=== Regular Expressions with multiple capture Groups ===&lt;br /&gt;
The regular expressions used in the above example for a Poolmanager will take the value that matches one capture group. This is the part of the regular expression inside (). In the above example &amp;quot;([\d\.]+)&amp;quot; refers to numerical digits or points between double quotation marks. Only the string consiting of digits and points will match inside (). This piece is assigned to the reading.&lt;br /&gt;
        &lt;br /&gt;
You can also use regular expressions that have several capture groups which might be helpful when parsing tables. In this case an attribute like &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading02Regex something[ \t]+([\d\.]+)[ \t]+([\d\.]+)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
could match two numbers. When you specify only one reading02Name like &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading02Name Temp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the name Temp will be used with the extension -1 and -2 thus giving a reading Temp-1 for the first number and Temp-2 for the second. You can also specify individual names for several readings that get parsed from one regular expression with several capture groups by defining attributes &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
reading02-1Name&lt;br /&gt;
reading02-2Name&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The same notation can be used for formatting attributes like readingXOMap, readingXFormat and so on.&lt;br /&gt;
&lt;br /&gt;
The usual way to define readings is however to have an individual regular expression with just one capture group per reading as shown in the above example.&lt;br /&gt;
&lt;br /&gt;
== Parsing JSON ==&lt;br /&gt;
    &lt;br /&gt;
If a webservice delivers data in JSON format, HTTPMOD can directly parse JSON which might be easier in this case than definig regular expressions.&lt;br /&gt;
The next example shows the data that can be requested from a Poolmanager with the following partial configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define test2 HTTPMOD none 0&lt;br /&gt;
attr test2 get01Name Chlor&lt;br /&gt;
attr test2 getURL http://192.168.70.90/cgi-bin/webgui.fcgi&lt;br /&gt;
attr test2 getHeader1 Content-Type: application/json&lt;br /&gt;
attr test2 getHeader2 Accept: */*&lt;br /&gt;
attr test2 getData {&amp;quot;get&amp;quot; :[&amp;quot;34.4008.value&amp;quot;]}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The data in the HTTP response looks like this:&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;data&amp;quot;: {&lt;br /&gt;
			&amp;quot;34.4008.value&amp;quot;: &amp;quot;0.25&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;status&amp;quot;:       {&lt;br /&gt;
			&amp;quot;code&amp;quot;: 0&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;event&amp;quot;:        {&lt;br /&gt;
			&amp;quot;type&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;data&amp;quot;: &amp;quot;48.30000.0&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the classic way to extract the value 0.25 into a reading with the name Chlor with a regex would have been&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr test2 get01Regex 34.4008.value&amp;quot;:[ \t]+&amp;quot;([\d\.]+)&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with JSON you can write &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr test2 get01JSON data_34.4008.value &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which will create a reading with the Name &amp;quot;Chlor&amp;quot; (as shown above) and take the value 0.25 from the JSON string.&lt;br /&gt;
&lt;br /&gt;
or if you don&#039;t care about the naming of your readings, you can simply extract all JSON data with &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr test2 extractAllJSON&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which would apply to all data read from this device and create the following readings out of the HTTP response shown above:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| data_34.4008.value || 0.25&lt;br /&gt;
|-&lt;br /&gt;
| event_data || 48.30000.0&lt;br /&gt;
|-&lt;br /&gt;
| event_type || 1&lt;br /&gt;
|-&lt;br /&gt;
| status_code || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
or you can specify&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr test2 get01ExtractAllJSON&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which would only apply to all data read as response to the get command defined as get01.        &lt;br /&gt;
&lt;br /&gt;
It might seem very simple at first sight to use extractAllJSON but if you prefer readings with a meaningful name you should instead define these readings with readingXXName and readingXXJSON or getXXName and getXXJSON individually. Of Course it would be possible to create additional user readings outside HTTPMOD but doing calculations, naming and formatting inside HTTPMOD is more efficient.&lt;br /&gt;
&lt;br /&gt;
=== JSON Lists ===&lt;br /&gt;
&lt;br /&gt;
imagine the HTTP Response contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
{ &amp;quot;power&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
  &amp;quot;modes&amp;quot;:[&amp;quot;Off&amp;quot;,&amp;quot;SimpleColor&amp;quot;,&amp;quot;RainbowChase&amp;quot;],&lt;br /&gt;
  &amp;quot;code1&amp;quot;:3,&lt;br /&gt;
  &amp;quot;code2&amp;quot;:4&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then a configuration like &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr device reading01JSON modes &lt;br /&gt;
attr device reading01Name Mode &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will create a list of Subreadings just like a regex with multiple matches can create multiple subreadings:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Mode-1 || Off&lt;br /&gt;
|-&lt;br /&gt;
| Mode-2  || SimpleColor&lt;br /&gt;
|-&lt;br /&gt;
| Mode-3 || RainbowChase &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
if you don&#039;t want several subreadings but one reading that contains the list of modes, you can specify a recombine expression:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr device reading01Name Modes &lt;br /&gt;
attr device reading01RecombineExpr join &amp;quot;,&amp;quot;, @matchlist &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which will create one reading containing a list:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Modes || Off,SimpleColor,RainbowChase&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
JSON parsing specifications also don&#039;t Need to match exactly. If there is no exact match for a defined reading, the HTTPMOD will try to Interpret the specification as a regex and look for json object paths that match the specification as a regex. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr device reading01Name CodeElem&lt;br /&gt;
attr device reading01JSON code&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which will create a list of readings:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| CodeElem-1|| 3&lt;br /&gt;
|-&lt;br /&gt;
| CodeElem-2  || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
and of course they could also be recombined into one reading with a RecombineExpr Attribute.&lt;br /&gt;
&lt;br /&gt;
== Parsing http / XML using xpath ==&lt;br /&gt;
Another alternative to regex parsing is the use of XPath to extract values from HTTP responses.&lt;br /&gt;
The following example shows how XML data can be parsed with XPath-Strict or HTML Data can be parsed with XPath.&lt;br /&gt;
Both work similar and the example uses XML Data parsed with the XPath-Strict option:&lt;br /&gt;
&lt;br /&gt;
If The XML data in the HTTP response looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;root xmlns:foo=&amp;quot;http://www.foo.org/&amp;quot; xmlns:bar=&amp;quot;http://www.bar.org&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;actors&amp;gt;&lt;br /&gt;
		&amp;lt;actor id=&amp;quot;1&amp;quot;&amp;gt;Peter X&amp;lt;/actor&amp;gt;&lt;br /&gt;
		&amp;lt;actor id=&amp;quot;2&amp;quot;&amp;gt;Charles Y&amp;lt;/actor&amp;gt;&lt;br /&gt;
		&amp;lt;actor id=&amp;quot;3&amp;quot;&amp;gt;John Doe&amp;lt;/actor&amp;gt;&lt;br /&gt;
	&amp;lt;/actor&amp;gt;&lt;br /&gt;
&amp;lt;/root&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with XPath you can write        &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr htest reading01Name Actor&lt;br /&gt;
attr htest reading01XPath-Strict //actor[2]/text()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a reading with the Name &amp;quot;Actor&amp;quot; and the value &amp;quot;Charles Y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Since XPath specifications can define several values / matches, HTTPMOD can also interpret these and store them in multiple readings:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr htest reading01Name Actor&lt;br /&gt;
attr htest reading01XPath-Strict //actor/text()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will create the readings &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Actor-1 || Peter X&lt;br /&gt;
|-&lt;br /&gt;
| Actor-2 || Charles Y&lt;br /&gt;
|-&lt;br /&gt;
| Actor-3 || John Doe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Further replacements of URL, header or post data ==&lt;br /&gt;
sometimes it might be helpful to dynamically change parts of a URL, HTTP header or post data depending on existing readings, internals or &lt;br /&gt;
perl expressions at runtime. This might be needed to pass further variables to a server, a current date or other things. &lt;br /&gt;
&lt;br /&gt;
To support this HTTPMOD offers generic replacements that are applied to a request before it is sent to the server. A replacement can be defined with the attributes &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;replacement[0-9]*Regex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;[gs]et[0-9]*Replacement[0-9]*Value&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a replacement always replaces a match of a regular expression. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;replacement[0-9]*Mode:&#039;&#039;&#039;&lt;br /&gt;
The way the replacement value is defined can be specified with the replacement mode.&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;reading&amp;lt;/code&amp;gt;, then the corresponding &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt; is interpreted as the name of a &#039;&#039;reading&#039;&#039; of the same device or as &#039;&#039;device:reading&#039;&#039; to refer to another device.&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;internal&amp;lt;/code&amp;gt;, then the corresponding &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt; is interpreted as the name of an &#039;&#039;internal&#039;&#039; of the same device or as &#039;&#039;device:internal&#039;&#039; to refer to another device.&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt;, then the corresponding &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt; is interpreted as a static text&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;expression&amp;lt;/code&amp;gt;, then the corresponding &amp;lt;code&amp;gt;replacement[0-9]*Value&amp;lt;/code&amp;gt; is evaluated as a perl expression to compute the replacement. Inside such a replacement expression it is possible to refer to capture groups of the replacement regex.&lt;br /&gt;
* If the &amp;lt;code&amp;gt;replacement[0-9]*Mode&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt;, then the module will use a value from a key / value pair that is stored in an obfuscated form in the file system with the set storeKeyValue command. This might be useful for storing passwords.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr mydevice getData {&amp;quot;get&amp;quot; :[&amp;quot;%%value%%.value&amp;quot;]}&lt;br /&gt;
attr mydevice replacement01Mode text&lt;br /&gt;
attr mydevice replacement01Regex %%value%%&lt;br /&gt;
&lt;br /&gt;
attr mydevice get01Name Chlor&lt;br /&gt;
attr mydevice get01Replacement01Value 34.4008&lt;br /&gt;
&lt;br /&gt;
attr mydevice get02Name Something&lt;br /&gt;
attr mydevice get02Replacement01Value 31.4024&lt;br /&gt;
&lt;br /&gt;
attr mydevice get05Name profile&lt;br /&gt;
attr mydevice get05URL http://www.mydevice.local/getprofile?password=%%password%%&lt;br /&gt;
attr mydevice replacement02Mode key&lt;br /&gt;
attr mydevice replacement02Regex %%password%%&lt;br /&gt;
attr mydevice get05Replacement02Value password&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;        &lt;br /&gt;
&lt;br /&gt;
defines that &amp;lt;code&amp;gt;%%value%%&amp;lt;/code&amp;gt; will be replaced by a static text.&lt;br /&gt;
&lt;br /&gt;
All Get commands will be HTTP post requests of a similar form. Only the &amp;lt;code&amp;gt;%%value%%&amp;lt;/code&amp;gt; will be different from get to get.&lt;br /&gt;
The first get will set the reading named Chlor and for the request it will take the generic getData and replace %%value%% with 34.4008.&lt;br /&gt;
&lt;br /&gt;
A second get will look the same except a different name and replacement value.&lt;br /&gt;
&lt;br /&gt;
With the command &amp;lt;code&amp;gt;set storeKeyValue password geheim&amp;lt;/code&amp;gt; you can store the password geheim in an obfuscated form in the file system. &lt;br /&gt;
To use this password and send it in a request you can use the above replacement with mode key. The value password will then refer to the ofuscated string stored with the key password.&lt;br /&gt;
&lt;br /&gt;
The mode &amp;lt;code&amp;gt;expression&amp;lt;/code&amp;gt; allows you to define your own replacement syntax:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;        &lt;br /&gt;
attr mydevice replacement01Mode expression&lt;br /&gt;
attr mydevice replacement01Regex {{([^}]+)}}&lt;br /&gt;
attr mydevice replacement01Value ReadingsVal(&amp;quot;mydevice&amp;quot;, $1, &amp;quot;&amp;quot;)&lt;br /&gt;
attr mydevice getData {&amp;quot;get&amp;quot; :[&amp;quot;{{temp}}.value&amp;quot;]}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;      &lt;br /&gt;
&lt;br /&gt;
In this example any &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{name}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; in a URL, header or post data will be passed on to the perl function ReadingsVal &lt;br /&gt;
which uses the string between &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; as second parameter. This way one defined replacement can be used for many different&lt;br /&gt;
readings.&lt;br /&gt;
&lt;br /&gt;
HTTPMOD has two built in replacements: One for session Ids and another one for the input value in a set command.&lt;br /&gt;
The placeholder $sid is always replaced with the internal &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt; which contains the session id after it is extracted from a previous HTTP response. &lt;br /&gt;
If you don&#039;t like to use the placeholder $sid then you can define your own replacement for example like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr mydevice replacement01Mode internal&lt;br /&gt;
attr mydevice replacement01Regex %session%&lt;br /&gt;
attr mydevice replacement01Value sid&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;      &lt;br /&gt;
&lt;br /&gt;
Now the internal &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt; will be used as a replacement for the placeholder %session%.&lt;br /&gt;
&lt;br /&gt;
In the same way a value that is passed to a set-command can be put into a request with a user defined replacement. &lt;br /&gt;
In this case the internal &amp;lt;code&amp;gt;$hash-&amp;gt;{value}&amp;lt;/code&amp;gt; will contain the value passed to the set command. &lt;br /&gt;
&amp;lt;code&amp;gt;$hash-&amp;gt;{value}&amp;lt;/code&amp;gt; might even be a string containing several values that could be put into several different positions in a request by using user defined replacements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Other example : steering a pellet stove from Rika&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The stove API of Rika on https://www.rika-firenet.com/web/ delivers a JSON string with all settings and values, and can be piloted with a data string containing all the &amp;quot;set&amp;quot; values at once.&lt;br /&gt;
&lt;br /&gt;
Delivered JSON on get https://www.rika-firenet.com/api/client/xxxxxxxx/status : (xxxxxxxx must be replaced with the unique stove ID)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Vorzimmer&amp;quot;,&lt;br /&gt;
    &amp;quot;stoveID&amp;quot;: &amp;quot;xxxxxxxxx&amp;quot;,&lt;br /&gt;
    &amp;quot;lastSeenMinutes&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;lastConfirmedRevision&amp;quot;: 1504385700,&lt;br /&gt;
    &amp;quot;controls&amp;quot;: {&lt;br /&gt;
        &amp;quot;revision&amp;quot;: 1504385700,&lt;br /&gt;
        &amp;quot;onOff&amp;quot;: true,&lt;br /&gt;
        &amp;quot;operatingMode&amp;quot;: 2,&lt;br /&gt;
        &amp;quot;heatingPower&amp;quot;: 65,&lt;br /&gt;
        &amp;quot;targetTemperature&amp;quot;: 24,&lt;br /&gt;
        &amp;quot;heatingTimesActive&amp;quot;: false,&lt;br /&gt;
        &amp;quot;heatingTimesActiveForComfort&amp;quot;: true,&lt;br /&gt;
        &amp;quot;setBackTemperature&amp;quot;: 18,&lt;br /&gt;
        &amp;quot;convectionFan1Active&amp;quot;: false,&lt;br /&gt;
        &amp;quot;convectionFan1Level&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;convectionFan1Area&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;convectionFan2Active&amp;quot;: false,&lt;br /&gt;
        &amp;quot;convectionFan2Level&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;convectionFan2Area&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;frostProtectionActive&amp;quot;: false,&lt;br /&gt;
        &amp;quot;frostProtectionTemperature&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;sensors&amp;quot;: {&lt;br /&gt;
        &amp;quot;statusError&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;statusWarning&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;statusService&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;statusMainState&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;statusSubState&amp;quot;: 3,&lt;br /&gt;
        &amp;quot;statusFrostStarted&amp;quot;: false,&lt;br /&gt;
        &amp;quot;inputFlameTemperature&amp;quot;: 21,&lt;br /&gt;
        &amp;quot;inputRoomTemperature&amp;quot;: 21,&lt;br /&gt;
        &amp;quot;inputExternalRequest&amp;quot;: true,&lt;br /&gt;
        &amp;quot;outputDischargeMotor&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;outputInsertionMotor&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;outputIDFan&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;outputAirFlaps&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;outputIgnition&amp;quot;: false,&lt;br /&gt;
        &amp;quot;parameterStoveTypeNumber&amp;quot;: 13,&lt;br /&gt;
        &amp;quot;parameterVersionMainBoard&amp;quot;: 223,&lt;br /&gt;
        &amp;quot;parameterVersionTFT&amp;quot;: 223,&lt;br /&gt;
        &amp;quot;parameterRuntimePellets&amp;quot;: 11,&lt;br /&gt;
        &amp;quot;parameterRuntimeLogs&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;parameterFeedRateTotal&amp;quot;: 17,&lt;br /&gt;
        &amp;quot;parameterFeedRateService&amp;quot;: 683,&lt;br /&gt;
        &amp;quot;parameterOnOffCycles&amp;quot;: 2&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;stoveType&amp;quot;: &amp;quot;DOMO MultiAir&amp;quot;,&lt;br /&gt;
    &amp;quot;stoveFeatures&amp;quot;: {&lt;br /&gt;
        &amp;quot;multiAir1&amp;quot;: true,&lt;br /&gt;
        &amp;quot;multiAir2&amp;quot;: true,&lt;br /&gt;
        &amp;quot;insertionMotor&amp;quot;: false,&lt;br /&gt;
        &amp;quot;airFlaps&amp;quot;: false,&lt;br /&gt;
        &amp;quot;logRuntime&amp;quot;: false&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Data string to send to https://www.rika-firenet.com/api/client/xxxxxxxx/controls in order to set values:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
heatingTimesActiveForComfort=true&amp;amp;frostProtectionTemperature=3&amp;amp;setBackTemperature=18&amp;amp;targetTemperature=24&amp;amp;convectionFan2Level=0&amp;amp;convectionFan2Active=false&amp;amp;convectionFan1Level=0&amp;amp;onOff=true&amp;amp;convectionFan1Active=false&amp;amp;convectionFan2Area=0&amp;amp;revision=1505550101&amp;amp;heatingTimesActive=false&amp;amp;convectionFan1Area=0&amp;amp;frostProtectionActive=false&amp;amp;operatingMode=2&amp;amp;heatingPower=65&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Code in 99_myUtils.pm:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
use JSON;&lt;br /&gt;
...&lt;br /&gt;
sub&lt;br /&gt;
replaceJSON ($$) {&lt;br /&gt;
   my ($valToReplace, $value) = @_;&lt;br /&gt;
&lt;br /&gt;
   #$value in the parameters is a default value&lt;br /&gt;
   #It has to be replaced through the real value nnn passed in the set command &amp;quot;set &amp;lt;device&amp;gt; valToset nnn&amp;quot;&lt;br /&gt;
   $value = InternalVal(&amp;quot;Ofen&amp;quot;, &amp;quot;value&amp;quot;, $value);&lt;br /&gt;
   Log3 (&amp;quot;Ofen&amp;quot;, 3, &amp;quot;replaceJSON Internalvalue: $value&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   #Force an update to avoid outdated revision number&lt;br /&gt;
   fhem (&amp;quot;get Ofen revision&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   #Get all the controls as json&lt;br /&gt;
   my $json = ReadingsVal(&amp;quot;Ofen&amp;quot;, &amp;quot;controlsJSON&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
   Log3 (&amp;quot;Ofen&amp;quot;, 3, &amp;quot;replaceJSON configsJSON: $json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   # When starting FHEM or rereading config, the reading controlsJSON is empty&lt;br /&gt;
   return if ($json eq &amp;quot;&amp;quot;); &lt;br /&gt;
&lt;br /&gt;
   my $decoded = decode_json($json);&lt;br /&gt;
   my $result;&lt;br /&gt;
   for my $key ( keys %$decoded ) {&lt;br /&gt;
      $result .= &amp;quot;$key=&amp;quot;;&lt;br /&gt;
      if ($key eq $valToReplace) {&lt;br /&gt;
         $result .= $value.&amp;quot;&amp;amp;&amp;quot;;&lt;br /&gt;
      } else {&lt;br /&gt;
         $result .= $decoded-&amp;gt;{$key}.&amp;quot;&amp;amp;&amp;quot;;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   chop($result); #remove last &amp;amp;&lt;br /&gt;
   Log3(&amp;quot;Ofen&amp;quot;, 3, &amp;quot;replaceJSON Result: $result&amp;quot;);&lt;br /&gt;
   return $result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Define stove in fhem:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
defmod Ofen HTTPMOD https://www.rika-firenet.com/api/client/xxxxxxxx/status 60&lt;br /&gt;
&lt;br /&gt;
attr Ofen enableCookies 1&lt;br /&gt;
attr Ofen reAuthRegex id=&amp;quot;login&amp;quot;|Unauthorized&lt;br /&gt;
attr Ofen sid01Data email=xx@xx&amp;amp;password=xx&lt;br /&gt;
attr Ofen sid01URL https://www.rika-firenet.com/web/login&lt;br /&gt;
&lt;br /&gt;
attr Ofen reading01JSON sensors_inputRoomTemperature&lt;br /&gt;
attr Ofen reading01Name RaumTemp&lt;br /&gt;
attr Ofen reading02JSON controls_setBackTemperature&lt;br /&gt;
attr Ofen reading02Name Absenkung&lt;br /&gt;
attr Ofen reading03JSON controls_frostProtectionTemperature&lt;br /&gt;
attr Ofen reading03Name Frostschutz&lt;br /&gt;
attr Ofen reading10Name controlsJSON&lt;br /&gt;
attr Ofen reading10Regex (?s)controls.*?({.*?})&lt;br /&gt;
&lt;br /&gt;
attr Ofen get09Name revision&lt;br /&gt;
attr Ofen get09URL https://www.rika-firenet.com/api/client/xxxxxxxx/status&lt;br /&gt;
&lt;br /&gt;
attr Ofen setURL https://www.rika-firenet.com/api/client/xxxxxxxx/controls&lt;br /&gt;
attr Ofen setData {{data}}&lt;br /&gt;
attr Ofen replacement01Mode expression&lt;br /&gt;
attr Ofen replacement01Regex {{data}}&lt;br /&gt;
&lt;br /&gt;
attr Ofen set11Name frostProtectionTemperature&lt;br /&gt;
attr Ofen set11Replacement01Value replaceJSON(&amp;quot;frostProtectionTemperature&amp;quot;, 2)&lt;br /&gt;
&lt;br /&gt;
attr Ofen set12Name targetTemperature&lt;br /&gt;
attr Ofen set12Replacement01Value replaceJSON(&amp;quot;targetTemperature&amp;quot;, 24)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A detailed explanation (in german) of the login process can be found here: [https://forum.fhem.de/index.php/topic,76220.msg682514.html#msg682514]&lt;br /&gt;
and the explanation of the other parameters here: [https://forum.fhem.de/index.php/topic,76220.msg685710.html#msg685710]&lt;br /&gt;
&lt;br /&gt;
== replacing reading values when they have not been updated / the device did not respond ==&lt;br /&gt;
If a device does not respond then the values stored in readings will keep the same and only their timestamp shows that they are outdated. &lt;br /&gt;
If you want to modify reading values that have not been updated for a number of seconds, you can use the attributes&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?MaxAge&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?MaxAgeReplacementMode&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(reading|get)[0-9]*(-[0-9]+)?MaxAgeReplacement&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every time the module tries to read from a device, it will also check if readings have not been updated &lt;br /&gt;
for longer than the &amp;lt;code&amp;gt;MaxAge&amp;lt;/code&amp;gt; attributes allow. If readings are outdated, the &amp;lt;code&amp;gt;MaxAgeReplacementMode&amp;lt;/code&amp;gt; defines how the affected&lt;br /&gt;
reading values should be replaced. &amp;lt;code&amp;gt;MaxAgeReplacementMode&amp;lt;/code&amp;gt; can be &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reading&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;internal&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;expression&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MaxAge&amp;lt;/code&amp;gt; specifies the number of seconds that a reading should remain untouched before it is replaced. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;MaxAgeReplacement&amp;lt;/code&amp;gt; contains either a static text that is used as replacement value or a Perl expression that is evaluated to &lt;br /&gt;
give the replacement value. This can be used for example to replace a temperature that has not bee updated for more than 5 minutes &lt;br /&gt;
with the string &amp;quot;outdated - was 12&amp;quot;:        &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM readingMaxAge 300&lt;br /&gt;
attr PM readingMaxAgeReplacement &amp;quot;outdated - was &amp;quot; . $val&lt;br /&gt;
attr PM readingMaxAgeReplacementMode expression&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The variable &amp;lt;code&amp;gt;$val&amp;lt;/code&amp;gt; contains the value of the reading before it became outdated.&lt;br /&gt;
&lt;br /&gt;
Or to show that a device was offline:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr MyLight reading01Name color&lt;br /&gt;
attr MyLight reading01JSON result_02_color&lt;br /&gt;
attr MyLight reading01MaxAge 300&lt;br /&gt;
attr MyLight reading01MaxAgeReplacement &amp;quot;offline&amp;quot;&lt;br /&gt;
attr MyLight reading01MaxAgeReplacementMode text&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Note on determining how to send requests to a special device ==&lt;br /&gt;
If you don&#039;t know which URLs, headers or POST data your web GUI uses, you might try a local proxy like BurpSuite [http://portswigger.net/burp/ BurpSuite] to track requests and responses. This is a tedious task but probably the best way to achieve a successful result. &lt;br /&gt;
&lt;br /&gt;
Let us consider an example. The Telekom Speedport W724V has a login-site that is famous for being cumbersome. Burp allows to monitor each step in the login procedure. In the case of a speedport the following steps occur:&lt;br /&gt;
&lt;br /&gt;
First burp shows that a get command is issued&lt;br /&gt;
 ################################################################################################## &lt;br /&gt;
 GET / HTTP/1.1&lt;br /&gt;
 Host: speedport.ip&lt;br /&gt;
 Cache-Control: max-age=0&lt;br /&gt;
 Upgrade-Insecure-Requests: 1&lt;br /&gt;
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36&lt;br /&gt;
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8&lt;br /&gt;
 Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4&lt;br /&gt;
 Cookie: lang=de&lt;br /&gt;
 Connection: close  &lt;br /&gt;
In order to mimic the behavior of a real person calling the website HTTPMOD should copy all necessary steps. Host, Cookie and the GET-command are usually necessary. The same cannot be said of the User-Agent because the website can be called from any mobile or desktop computer. &lt;br /&gt;
&lt;br /&gt;
Then, the speedport will answer with a command that consists of several lines. By going through every line for every step in the login procedure one will finally arrive at the information that is necessary to successfully enter the login of the speedport (in case of the W724V, for example, it is necessary to copy a token called _httoken and to include the referer).&lt;br /&gt;
&lt;br /&gt;
== Advanced configuration to define a &amp;lt;code&amp;gt;set&amp;lt;/code&amp;gt; command and send data to a device ==&lt;br /&gt;
       &lt;br /&gt;
When a set option is defined by attributes, the module will use the value given to the set command and integrate it into an HTTP-Request that sends the value to the device. The definitions for URL, headers and post data can contain the placeholder $val which will be replaced by the value given to the set command.&lt;br /&gt;
&lt;br /&gt;
This can be as simple as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
# No cyclic requests and no main URL needed in this example&lt;br /&gt;
define MyDevice HTTPMOD none 0&lt;br /&gt;
&lt;br /&gt;
attr MyDevice set01Name Licht&lt;br /&gt;
attr MyDevice set01URL http://192.168.1.22/switch=$val&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A user command &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
set MyDevice Licht 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will be translated into the http GET request&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
http://192.168.1.22/switch=1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a map would also be helpful, that translates on / off to 0 or 1 and allows the user to select on/of in fhemweb:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr MyDevive set01IMap 0:off, 1:on&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This also provides input validation to make sure that only on and off can be used with the set command.&lt;br /&gt;
&lt;br /&gt;
In more complex Scenarios you might need to login before sending a command and the Login might create a session id that has to be part of further requests either in the URL, in headers or in the post data.&lt;br /&gt;
&lt;br /&gt;
Extension to the above example for a PoolManager 5 where a set needs a session id in the URL and the values have to be passed in JSON strings as post data:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM set01Name HeizungSoll&lt;br /&gt;
attr PM set01URL http://MyPoolManager/cgi-bin/webgui.fcgi?sid=$sid&lt;br /&gt;
attr PM set01Hint 6,10,20,30&lt;br /&gt;
attr PM set01Min 6&lt;br /&gt;
attr PM set01Max 30&lt;br /&gt;
attr PM setHeader1 Content-Type: application/json&lt;br /&gt;
attr PM set01Data {&amp;quot;set&amp;quot; :{&amp;quot;34.3118.value&amp;quot; :&amp;quot;$val&amp;quot; }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example defines a set option with the name HeizungSoll.&lt;br /&gt;
By issuing &amp;lt;code&amp;gt;set PM HeizungSoll 10&amp;lt;/code&amp;gt; in FHEM, the value 10 will be sent in the defined HTTP&lt;br /&gt;
Post to URL &amp;lt;code&amp;gt;http://MyPoolManager/cgi-bin/webgui.fcgi&amp;lt;/code&amp;gt; in the Post Data as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
{&amp;quot;set&amp;quot; :{&amp;quot;34.3118.value&amp;quot; :&amp;quot;10&amp;quot; }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The optional attributes set01Min and set01Max define input validations that will be checked in the set function. &lt;br /&gt;
The optional attribute set01Hint will define a selection list for the FHEMweb GUI.&lt;br /&gt;
&lt;br /&gt;
The HTTP response to such a request will be ignored unless you specify the attribute &amp;lt;code&amp;gt;setParseResponse&amp;lt;/code&amp;gt; &lt;br /&gt;
for all set commands or &amp;lt;code&amp;gt;set01ParseResponse&amp;lt;/code&amp;gt; for the set command with number 01.&lt;br /&gt;
If the HTTP response to a set command is parsed then this is done like the parsing of responses to get commands and you can use the attributes ending e.g. on Format, Encode, Decode, OMap and OExpr to manipulate / format the values read.&lt;br /&gt;
&lt;br /&gt;
If a parameter to a set command is not numeric but should be passed on to the device as text, then you can specify the attribute setTextArg. For example: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM set01TextArg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a set command should not require a parameter at all, then you can specify the attribute NoArg. For example: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM set03Name On&lt;br /&gt;
attr PM set03NoArg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced configuration to create a valid session id that might be necessary ==&lt;br /&gt;
In simple cases logging in works with basic authentication. In the case HTTPMOD accepts a username and password as part of the URL in the form &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
http://User:Password@192.168.1.18/something&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However basic auth is seldom used. If you need to fill in a username and password in a HTML form and the session is then managed by a session id, here is how to configure this:&lt;br /&gt;
&lt;br /&gt;
when sending data to an HTTP-Device in a set, HTTPMOD will replace any &amp;lt;code&amp;gt;$sid&amp;lt;/code&amp;gt; in the URL, Headers and Post data with the internal &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt;. To authenticate towards the device and give this internal a value, you can use an optional multi step login procedure defined by the following attributes: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;sid[0-9]*URL&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sid[0-9]*Data.*&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sid[0-9]*Header.*&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sid[0-9]*IgnoreRedirects&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;idRegex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;idJSON&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;idXPath&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;idXPath-Strict&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set|sid)[0-9]*IdRegex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set|sid)[0-9]*IdJSON&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set|sid)[0-9]*IdXPath&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set|sid)[0-9]*IdXPath-Strict&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each step can have a URL, Headers, Post Data pieces and a Regex to extract a resulting Session ID into &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt;.&lt;br /&gt;
HTTPMOD will create a sorted list of steps (the numbers between sid and URL / Data / Header) and the loop through these steps and send the corresponding requests to the device. For each step a $sid in a Header or Post Data will be replaced with the current content of &amp;lt;code&amp;gt;$hash-&amp;gt;{sid}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Using this feature, HTTPMOD can perform a forms based authentication and send user name, password or other necessary data to the device and save the session id for further requests.&lt;br /&gt;
        &lt;br /&gt;
To determine when this login procedure is necessary, HTTPMOD will first try to send a request without &lt;br /&gt;
doing the login procedure. If the result contains an error that authentication is necessary, then a login is performed. &lt;br /&gt;
To detect such an error in the HTTP response, you can again use a regular expression, JSON or XPath, this time with the attributes &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;reAuthRegex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reAuthJSON&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reAuthXPath&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;reAuthXPath-Strict&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set)[0-9]*ReAuthRegex&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set)[0-9]*ReAuthJSON&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set)[0-9]*ReAuthXPath&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;(get|set)[0-9]*ReAuthXPath-Strict&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reAuthJSON or reAuthXPath typically only extract one piece of data from a response. &lt;br /&gt;
If the existence of the specified piece of data is sufficent to start a login procedure, then nothing more needs to be defined to detect this situation. &lt;br /&gt;
If however the indicator is a status code that contains different values depending on a successful request and a failed request if a new authentication is needed, &lt;br /&gt;
then you can combine things like reAuthJSON with reAuthRegex. In this case the regex is only matched to the data extracted by JSON (or XPath). &lt;br /&gt;
This way you can easily extract the status code using JSON parsing and then specify the code that means &amp;quot;authentication needed&amp;quot; as a regular expression.&lt;br /&gt;
        &lt;br /&gt;
If for one step not all of the URL, Data or Header Attributes are set, then HTTPMOD tries to use a &lt;br /&gt;
&amp;lt;code&amp;gt;sidURL&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sidData.*&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sidHeader.*&amp;lt;/code&amp;gt; Attribute (without the step number after sid). This way parts that are the same for all steps don&#039;t need to be defined redundantly.&lt;br /&gt;
&lt;br /&gt;
=== Example for a multi step login procedure: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM reAuthRegex /html/dummy_login.htm &lt;br /&gt;
attr PM sidURL http://192.168.70.90/cgi-bin/webgui.fcgi?sid=$sid&lt;br /&gt;
attr PM sidHeader1 Content-Type: application/json&lt;br /&gt;
attr PM sid1IDRegex wui.init\(&#039;([^&#039;]+)&#039;&lt;br /&gt;
attr PM sid2Data {&amp;quot;set&amp;quot; :{&amp;quot;9.17401.user&amp;quot; :&amp;quot;fhem&amp;quot; ,&amp;quot;9.17401.pass&amp;quot; :&amp;quot;password&amp;quot; }}&lt;br /&gt;
attr PM sid3Data {&amp;quot;set&amp;quot; :{&amp;quot;35.5062.value&amp;quot; :&amp;quot;128&amp;quot; }}&lt;br /&gt;
attr PM sid4Data {&amp;quot;set&amp;quot; :{&amp;quot;42.8026.code&amp;quot; :&amp;quot;pincode&amp;quot; }}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case HTTPMOD detects that a login is necessary by looking for the pattern /html/dummy_login.htm in the HTTP response. &lt;br /&gt;
If it matches, it starts a login sequence. In the above example all steps request the same URL. In step 1 only the defined Header is sent in an HTTP get request. The response will contain a session id that is extraced with the regex wui.init\(&#039;([^&#039;]+)&#039;.&lt;br /&gt;
&lt;br /&gt;
In the next step this session id is sent in a post request to the same URL where tha post data contains a username and password. The a third and a fourth request follow that set a value and a code. The result will be a valid and authorized session id that can be used in other requests where $sid is part of a URL, header or post data and will be replaced with the session id extracted above.&lt;br /&gt;
&lt;br /&gt;
In the special case where a session id is set as a HTTP-Cookie (with the header Set-cookie: in the HTTP response) HTTPMOD offers an even simpler way. With the attribute enableCookies a very basic cookie handling mechanism is activated that stores all cookies that the server sends to the HTTPMOD device and puts them back as cookie headers in the following requests.&lt;br /&gt;
&lt;br /&gt;
For such cases no sidIdRegex and no $sid in a user defined header is necessary.&lt;br /&gt;
&lt;br /&gt;
== Advanced configuration to define a &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; and request additional data with its own request from a device ==&lt;br /&gt;
&lt;br /&gt;
The normal automatic HTTP request that is done repeatedly after the defined interval has elapsed works well in cases where all required readings can be requested in one common HTTP request. If however a device needs individual requests with different URLs or different POST data for each value, then another method is necessary. &lt;br /&gt;
For such cases a &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; option can be defined and the user can either issue FHEM &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; commands each time he needs the reading or the user can set an attribute to request the reading automatically together with the normal iteration.&lt;br /&gt;
For each &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; option attributes define an individual URL, optional headers, and post data as well as individual regular expressions and formatting options. &lt;br /&gt;
&lt;br /&gt;
When a get option is defined by attributes, the module allows querying additional values from the device that require individual HTTP-Requests or special parameters to be sent&lt;br /&gt;
&lt;br /&gt;
Extension to the above example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM get01Name MyGetValue &amp;lt;br&amp;gt;&lt;br /&gt;
attr PM get01URL http://MyPoolManager/cgi-bin/directory/webgui.fcgi?special=1?sid=$sid &amp;lt;br&amp;gt;&lt;br /&gt;
attr PM getHeader1 Content-Type: application/json &amp;lt;br&amp;gt;&lt;br /&gt;
attr PM get01Data {&amp;quot;get&amp;quot; :{&amp;quot;30.1234.value&amp;quot;}} &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example defines a get option with the name MyGetValue.&lt;br /&gt;
By issuing &amp;lt;code&amp;gt;get PM MyGetValue&amp;lt;/code&amp;gt; in FHEM, the defined HTTP request is sent to the device.&lt;br /&gt;
The HTTP response is then parsed using the same readingXXName and readingXXRegex attributes as above so&lt;br /&gt;
additional pairs will probably be needed there for additional values.&lt;br /&gt;
&lt;br /&gt;
if you prefer to define the parsing and formatting of readings individually per get command, you can use &lt;br /&gt;
attributes like get01Regex, get01XPath, get01Format, get01OMap and so on just like for reading01...&lt;br /&gt;
&lt;br /&gt;
You can also include parameters / values that are passed to the get command in the request just like for set commands.&lt;br /&gt;
The placeholder $val will be replaced with the value given to the get command or you can specify your own replacement as described above.&lt;br /&gt;
&lt;br /&gt;
If the new get parameter should also be queried regularly, you can define the following optional attributes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
attr PM get01Poll 1&lt;br /&gt;
attr PM get01PollDelay 300&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first attribute includes this reading in the automatic update cycle and the second defines an alternative lower update frequency. When the interval defined initially in the define is over and the normal readings are read from the device, the update function will check for additional get parameters that should be included in the update cycle.&lt;br /&gt;
&lt;br /&gt;
If a PollDelay is specified for a get parameter, the update function also checks if the time passed since it has last read this value is more than the given PollDelay. If not, this reading is skipped and it will be rechecked in the next cycle when interval is over again. So the effective PollDelay will always be a multiple of the interval specified in the initial define.&lt;br /&gt;
&lt;br /&gt;
Please note that each defined get command that is included in the regular update cycle will create its own HTTP request. So if you want to extract several values from the same request, it is much more efficient to do this by defining readingXXName and readingXXRegex, XPath or JSON attributes and to specify an interval and a URL in the define of the HTTPMOD device. &lt;br /&gt;
&lt;br /&gt;
Example for a Siemens webserver provided by Lanhydrock:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
define ozw672 HTTPMOD https://192.168.178.8/api/auth/login.json?user=test&amp;amp;pwd=test 300&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get1Name tempAussen&lt;br /&gt;
attr ozw672 get1URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1960&lt;br /&gt;
attr ozw672 get1Poll 1&lt;br /&gt;
attr ozw672 get1PollDelay 1800&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get2Name tempAussenGemischt&lt;br /&gt;
attr ozw672 get2URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1964&lt;br /&gt;
attr ozw672 get2Poll 1&lt;br /&gt;
attr ozw672 get2PollDelay 1800&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get3Name tempTWW&lt;br /&gt;
attr ozw672 get3URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1996&lt;br /&gt;
attr ozw672 get3Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get4Name tempKesselSoll&lt;br /&gt;
attr ozw672 get4URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1910&lt;br /&gt;
attr ozw672 get4Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get5Name tempKesselRuecklauf&lt;br /&gt;
attr ozw672 get5URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1915&lt;br /&gt;
attr ozw672 get5Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get6Name tempKesselRuecklaufSoll&lt;br /&gt;
attr ozw672 get6URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1916&lt;br /&gt;
attr ozw672 get6Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get7Name anzahlStartsBrenner&lt;br /&gt;
attr ozw672 get7URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1927&lt;br /&gt;
attr ozw672 get7PollDelay 1800&lt;br /&gt;
attr ozw672 get7Poll 1&lt;br /&gt;
&lt;br /&gt;
attr ozw672 get8Name statusKessel&lt;br /&gt;
attr ozw672 get8URL https://192.168.178.8/api/menutree/read_datapoint.json?SessionId=$sid&amp;amp;Id=1898&lt;br /&gt;
attr ozw672 get8Poll 1&lt;br /&gt;
attr ozw672 get8Regex Value&amp;quot;: &amp;quot;([a-zA-Zü ]*)&amp;quot;&lt;br /&gt;
attr ozw672 get8OMap Aus:0, Nachlauf aktiv:5, Freigegeben für TWW:10, Freigegeben für HK:20, In Teillastbetrieb für TWW:40, In Teillastbetrieb für HK:50, In Betrieb für Trinkwasser:90, In Betrieb für Heizkreis:100&lt;br /&gt;
&lt;br /&gt;
attr ozw672 getRegex Value&amp;quot;: &amp;quot;[ ]*([-.0-9]*)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
attr ozw672 reAuthRegex .*session not valid.*&lt;br /&gt;
attr ozw672 sid1IDRegex .*&amp;quot;(.*-.*-.*-[0-9a-z]*).*&lt;br /&gt;
attr ozw672 sid1URL https://192.168.178.8/api/auth/login.json?user=test&amp;amp;pwd=test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== All attributes ==&lt;br /&gt;
;reading[0-9]+Name&lt;br /&gt;
:the name of a reading to extract with the corresponding readingRegex, readingJSON, readingXPath or readingXPath-Strict&lt;br /&gt;
:Please note that the old syntax &amp;lt;b&amp;gt;readingsName.*&amp;lt;/b&amp;gt; does not work with all features of HTTPMOD and should be avoided. It might go away in a future version of HTTPMOD.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]+Name&lt;br /&gt;
:Name of a get or set command&lt;br /&gt;
:If the HTTP response that is received after the command is parsed with an individual parse option then this name is also used as a reading name. Please note that no individual parsing needs to be defined for a get or set. If no regex, XPath or JSON is specified for the command, then HTTPMOD will try to parse the response using all the defined readingRegex, reading XPath or readingJSON attributes.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+Regex&lt;br /&gt;
:If this attribute is specified, the Regex defined here is used to extract the value from the HTTP Response and assign it to a Reading with the name defined in the (get|set|reading)[0-9]+Name attribute.&lt;br /&gt;
:If this attribute is not specified for an individual Reading or get or set but without the numbers in the middle, e.g. as getRegex or readingRegex, then it applies to all the other readings / get / set commands where no specific Regex is defined.&amp;lt;br&amp;gt;&lt;br /&gt;
:The value to extract should be in a capture group / sub expression e.g. ([\d\.]+) in the above example. Multiple capture groups will create multiple readings (see explanation above)&lt;br /&gt;
:Using this attribute for a set command (setXXRegex) only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
:Please note that the old syntax &amp;lt;code&amp;gt;readingsRegex.*&amp;lt;/code&amp;gt; does not work with all features of HTTPMOD and should be avoided. It might go away in a future version of HTTPMOD.&lt;br /&gt;
:If for get or set commands neither a generic Regex attribute without numbers nor a specific (get|set)[0-9]+Regex attribute is specified and also no XPath or JSON parsing specification is given for the get or set command, then HTTPMOD tries to use the parsing definitions for general readings defined in reading[0-9]+Name, reading[0-9]+Regex or XPath or JSON attributes and assigns the Readings that match here.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+RegOpt&lt;br /&gt;
:Lets the user specify regular expression modifiers. For example if the same regular expression should be matched as often as possible in the HTTP response, then you can specify RegOpt g which will case the matching to be done as /regex/g&lt;br /&gt;
:The results will be trated the same way as multiple capture groups so the reading name will be extended with -number. &lt;br /&gt;
:For other possible regular expression modifiers see http://perldoc.perl.org/perlre.html#Modifiers&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+XPath&lt;br /&gt;
:defines an xpath to one or more values when parsing HTML data (see examples above)&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;get|set|reading[0-9]+XPath-Strict&lt;br /&gt;
:defines an xpath to one or more values when parsing XML data (see examples above)&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+AutoNumLen&lt;br /&gt;
:In cases where a regular expression or an XPath results in multiple results and these results are stored in a common reading name with extension -number, then you can modify the format of this number to have a fixed length with leading zeros. AutoNumLen 3 for example will lead to reading names ending with -001 -002 and so on.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]+AlwaysNum&lt;br /&gt;
:if set to 1 this attributes forces reading names to end with a -1, -01 (depending on the above described AutoNumLen) even if just one value is parsed.&lt;br /&gt;
&lt;br /&gt;
;get|set|reading[0-9]+JSON&lt;br /&gt;
:defines a path to the JSON object wanted by concatenating the object names. See the above example.&lt;br /&gt;
:If you don&#039;t know the paths, then start by using extractAllJSON and the use the names of the readings as values for the JSON attribute.&amp;lt;br&amp;gt;&lt;br /&gt;
:Please don&#039;t forget to also specify a name for a reading, get or set. &lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]*RecombineExpr&lt;br /&gt;
:defines an expression that is used in an eval to compute one reading value out of the list of matches.&lt;br /&gt;
:This is supposed to be used for regexes or xpath specifications that produce multiple results if only one result that combines them is wanted. The list of matches will be in the variable @matchlist.&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;get[0-9]*CheckAllReadings&lt;br /&gt;
:this attribute modifies the behavior of HTTPMOD when the HTTP Response of a get command is parsed. &amp;lt;br&amp;gt;&lt;br /&gt;
:If this attribute is set to 1, then additionally to the matching of the corresponding get specific regex (get[0-9]*Regex), XPath or JSON attribute also all the reading names and parse definitions defined in Reading[0-9]+Name and Reading[0-9]+Regex, XPath or JSON attributes are checked and if they match, the coresponding Readings are assigned as well.&lt;br /&gt;
:Please note that this does not mean that get01CheckAllReadings will cause a get02Regex to be used. Only the corresponding get01Regex will be used but additionally all the readingXYRegex attributes.&lt;br /&gt;
:This is automatically done if a get or set command is defined without its own parse attributes.&lt;br /&gt;
&lt;br /&gt;
;(get|reading)[0-9]*OExpr&lt;br /&gt;
:defines an optional expression that is used in an eval to compute / format a readings value after parsing an HTTP response&lt;br /&gt;
:The raw value from the parsing will be in the variable $val.&lt;br /&gt;
:If specified as readingOExpr then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*Expr.&lt;br /&gt;
:Please note that the old syntax &amp;lt;b&amp;gt;readingsExpr.*&amp;lt;/b&amp;gt; does not work with all features of HTTPMOD and should be avoided. It might go away in a future version of HTTPMOD.&lt;br /&gt;
&lt;br /&gt;
;(get|reading)[0-9]*Expr&lt;br /&gt;
:This is the old syntax for (get|reading)[0-9]*OExpr. It should be replaced by (get|reading)[0-9]*OExpr. The set command upgradeAttributes which becomes visible when the attribute enableControlSet is set to 1, can do this renaming automatically.&lt;br /&gt;
&lt;br /&gt;
;(get|reading)[0-9]*OMap&lt;br /&gt;
:Map that defines a mapping from raw value parsed to visible values like &amp;quot;0:mittig, 1:oberhalb, 2:unterhalb&amp;quot;.&lt;br /&gt;
:If specified as readingOMap then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*Map.&amp;lt;br&amp;gt;&lt;br /&gt;
:The individual options in a map are separated by a komma and an optional space. Spaces are allowed to appear in a visible value however kommas are not possible.&lt;br /&gt;
&lt;br /&gt;
;(get|reading)[0-9]*Map&lt;br /&gt;
:This is the old syntax for (get|reading)[0-9]*OMap. It should be replaced by (get|reading)[0-9]*OMap. The set command upgradeAttributes which becomes visible when the attribute enableControlSet is set to 1, can do this renaming automatically.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]*Format&lt;br /&gt;
:Defines a format string that will be used in sprintf to format a reading value.&lt;br /&gt;
:If specified without the numbers in the middle e.g. as readingFormat then the attribute value is a default for all other readings that don&#039;t specify an explicit reading[0-9]*Format.&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]*Decode&lt;br /&gt;
:defines an encoding to be used in a call to the perl function decode to convert the raw data string read from the device to a reading. &lt;br /&gt;
:This can be used if the device delivers strings in an encoding like cp850 instead of utf8.&lt;br /&gt;
:If your reading values contain Umlauts and they are shown as strange looking icons then you probably need to use this feature.&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;(get|set|reading)[0-9]*Encode&lt;br /&gt;
:defines an encoding to be used in a call to the perl function encode to convert the raw data string read from the device to a reading. &lt;br /&gt;
:This can be used if the device delivers strings in an encoding like cp850 and after decoding it you want to reencode it to e.g. utf8.&lt;br /&gt;
:If your reading values contain Umlauts and they are shown as strange looking icons then you probably need to use this feature.&lt;br /&gt;
:Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*URL&lt;br /&gt;
:URL to be requested for the set or get command. If this option is missing, the URL specified during define will be used.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*Data&lt;br /&gt;
:Data to be sent to the device as POST data when the get or set command is executed. if this attribute is not specified, an HTTP GET method will be used instead of an HTTP POST&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*NoData&lt;br /&gt;
:can be used to override a more generic attribute that specifies POST data for all get or set commands. With NoData no data is sent and therefor the request will be an HTTP GET.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*Header.*&lt;br /&gt;
:HTTP Headers to be sent to the device when the set is executed&lt;br /&gt;
&lt;br /&gt;
;requestHeader.*&lt;br /&gt;
:Define an optional additional HTTP Header to set in the HTTP request of the main loop&lt;br /&gt;
&lt;br /&gt;
;requestData&lt;br /&gt;
:optional POST Data to be sent in the request of the main loop. If not defined, it will be an HTTP GET request as defined in HttpUtils which is used by this module&lt;br /&gt;
&lt;br /&gt;
;get[0-9]+Poll&lt;br /&gt;
:if set to 1 the get is executed automatically during the normal update cycle (after the interval provided in the define command has elapsed)&lt;br /&gt;
&lt;br /&gt;
;get[0-9]+PollDelay&lt;br /&gt;
:if the value should not be read in each iteration (after the interval given to the define command), then a minimum delay can be specified with this attribute. This has only an effect if the above Poll attribute has also been set. Every time the update function is called, it checks if since this get has been read the last time, the defined delay has elapsed. If not, then it is skipped this time.&lt;br /&gt;
:PollDelay can be specified as seconds or as x[0-9]+ which means a multiple of the interval in the define command.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*TextArg&lt;br /&gt;
:For a get command this defines that the command accepts a text value after the option name. By default a get command doesn&#039;t accept optional values after the command name. &lt;br /&gt;
:If TextArg is specified and a value is passed after the get name then this value can then be used in a request URL, header or data as replacement for $val or in a user defined replacement that uses the internal &amp;quot;value&amp;quot; ($hash-&amp;gt;{value}).&lt;br /&gt;
:If used for a set command then it defines that the value to be set doesn&#039;t require any validation / conversion. &lt;br /&gt;
:The raw value is passed on as text to the device. By default a set command expects a numerical value or a text value that is converted to a numeric value using a map.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Min&lt;br /&gt;
:Minimum value for input validation. &lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Max&lt;br /&gt;
:Maximum value for input validation. &lt;br /&gt;
&lt;br /&gt;
;set[0-9]+IExpr&lt;br /&gt;
:Perl Expression to compute the raw value to be sent to the device from the input value passed to the set.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Expr&lt;br /&gt;
:This is the old syntax for (get|reading)[0-9]*IExpr. It should be replaced by (get|reading)[0-9]*IExpr. The set command upgradeAttributes which becomes visible when the attribute enableControlSet is set to 1, can do this renaming automatically.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+IMap&lt;br /&gt;
:Map that defines a mapping from raw to input values like &amp;quot;0:mittig, 1:oberhalb, 2:unterhalb&amp;quot;. This attribute atomatically creates a hint for FHEMWEB so the user can choose one of the input values.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Map&lt;br /&gt;
:This is the old syntax for (get|reading)[0-9]*IMap. It should be replaced by (get|reading)[0-9]*IMap. The set command upgradeAttributes which becomes visible when the attribute enableControlSet is set to 1, can do this renaming automatically.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]+Hint&lt;br /&gt;
:Explicit hint for fhemWEB that will be returned when set ? is seen. Can be used to get a slider or a list of values to choose from.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]*NoArg&lt;br /&gt;
:Defines that this set option doesn&#039;t require arguments. It allows sets like &amp;quot;on&amp;quot; or &amp;quot;off&amp;quot; without further values.&lt;br /&gt;
&lt;br /&gt;
;set[0-9]*ParseResponse&lt;br /&gt;
:defines that the HTTP response to the set will be parsed as if it was the response to a get command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*URLExpr&lt;br /&gt;
:Defines a Perl expression to specify the HTTP Headers for this request. This overwrites any other header specification and should be used carefully only if needed. The original Header is availabe as $old. Typically this feature is not needed and it might go away in future versions of HTTPMOD. Please use the &amp;quot;replacement&amp;quot; attributes if you want to pass additional variable data to a web service. &lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*DatExpr&lt;br /&gt;
:Defines a Perl expression to specify the HTTP Post data for this request. This overwrites any other post data specification and should be used carefully only if needed. The original Data is availabe as $old. Typically this feature is not needed and it might go away in future versions of HTTPMOD. Please use the &amp;quot;replacement&amp;quot; attributes if you want to pass additional variable data to a web service. &lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*HdrExpr&lt;br /&gt;
:Defines a Perl expression to specify the URL for this request. This overwrites any other URL specification and should be used carefully only if needed. The original URL is availabe as $old. Typically this feature is not needed and it might go away in future versions of HTTPMOD. Please use the &amp;quot;replacement&amp;quot; attributes if you want to pass additional variable data to a web service.           &lt;br /&gt;
&lt;br /&gt;
;ReAuthRegex&lt;br /&gt;
:regular Expression to match an error page indicating that a session has expired and a new authentication for read access needs to be done. &lt;br /&gt;
:This attribute only makes sense if you need a forms based authentication for reading data and if you specify a multi step login procedure based on the sid.. attributes.&lt;br /&gt;
:This attribute is used for all requests. For set and get operations you can however specify individual reAuthRegexes with the (get|set)[0-9]*ReAuthRegex attributes.&lt;br /&gt;
&lt;br /&gt;
;(get|set)[0-9]*ReAuthRegex&lt;br /&gt;
:Regex that will detect when a session has expired during a set operation and a new login needs to be performed.&lt;br /&gt;
:It works like the global reAuthRegex but is used for set operations.&lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*URL&lt;br /&gt;
:different URLs or one common URL to be used for each step of an optional login procedure. &lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*IDRegex&lt;br /&gt;
:different Regexes per login procedure step or one common Regex for all steps to extract the session ID from the HTTP response&lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*Data.*&lt;br /&gt;
:data part for each step to be sent as POST data to the corresponding URL&lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*Header.*&lt;br /&gt;
:HTTP Headers to be sent to the URL for the corresponding step&lt;br /&gt;
&lt;br /&gt;
;sid[0-9]*IgnoreRedirects&lt;br /&gt;
:Tells the HttpUtils to not follow HTTP Redirects for this Request. Might be needed for some devices that set a session cookie within a 303 Redirect.&lt;br /&gt;
&lt;br /&gt;
;clearSIdBeforeAuth&lt;br /&gt;
:will set the session id to &amp;quot;&amp;quot; before doing the authentication steps&lt;br /&gt;
&lt;br /&gt;
;authRetries&lt;br /&gt;
:number of retries for authentication procedure - defaults to 1&lt;br /&gt;
&lt;br /&gt;
;replacement[0-9]*Regex&lt;br /&gt;
:Defines a replacement to be applied to an HTTP request header, data or URL before it is sent. This allows any part of the request to be modified based on a reading, an internal or an expression.&lt;br /&gt;
:The regex defines which part of a header, data or URL should be replaced. The replacement is defined with the following attributes:&lt;br /&gt;
&lt;br /&gt;
;replacement[0-9]*Mode&lt;br /&gt;
:Defines how the replacement should be done and what replacementValue means. Valid options are text, reading, internal and expression.&lt;br /&gt;
&lt;br /&gt;
;replacement[0-9]*Value&lt;br /&gt;
:Defines the replacement. If the corresponding replacementMode is &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt;, then value is a static text that is used as the replacement.&lt;br /&gt;
:If replacementMode is &amp;lt;code&amp;gt;reading&amp;lt;/code&amp;gt; then Value can be the name of a reading of this device or it can be a reading of a different device referred to by devicename:reading.&lt;br /&gt;
:If replacementMode is &amp;lt;code&amp;gt;internal&amp;lt;/code&amp;gt; the Value can be the name of an internal of this device or it can be an internal of a different device referred to by devicename:internal.&lt;br /&gt;
:If replacementMode is &amp;lt;code&amp;gt;expression&amp;lt;/code&amp;gt; the the Value is treated as a Perl expression that computes the replacement value. The expression can use $1, $2 and so on to refer to capture groups of the corresponding regex that is matched against the original URL, header or post data.&lt;br /&gt;
:If replacementMode is &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; then the module will use a value from a key / value pair that is stored in an obfuscated form in the file system with the set storeKeyValue command. This might be useful for storing passwords.&lt;br /&gt;
&lt;br /&gt;
;[gs]et[0-9]*Replacement[0-9]*Value&lt;br /&gt;
:This attribute can be used to override the replacement value for a specific get or set.&lt;br /&gt;
&lt;br /&gt;
;get|reading[0-9]*MaxAge&lt;br /&gt;
:Defines how long a reading is valid before it is automatically overwritten with a replacement when the read function is called the next time.&lt;br /&gt;
&lt;br /&gt;
;get|reading[0-9]*MaxAgeReplacement&lt;br /&gt;
:specifies the replacement for MaxAge - either as a static text or as a perl expression.&lt;br /&gt;
&lt;br /&gt;
;get|reading[0-9]*MaxAgeReplacementMode&lt;br /&gt;
:specifies how the replacement is interpreted: can be text, expression and delete.&lt;br /&gt;
&lt;br /&gt;
;get|reading[0-9]*DeleteIfUnmatched&lt;br /&gt;
:If set to 1 this attribute causes certain readings to be deleted when the parsing of the website does not match the specified reading. Internally HTTPMOD remembers which kind of operation created a reading (update, Get01, Get02 and so on). Specified readings will only be deleted if the same operation does not parse this reading again. This is especially useful for parsing that creates several matches / readings and the number of matches can vary from request to request. For example if reading01Regex creates 4 readings in one update cycle and in the next cycle it only matches two times then the readings containing the remaining values from the last round will be deleted.&lt;br /&gt;
:Please note that this mechanism will not work in all cases after a restart. Especially when a get definition does not contain its own parsing definition but ExtractAllJSON or relies on HTTPMOD to use all defined reading.* attributes to parse the responsee to a get command, old readings might not be deleted after a restart of fhem.&lt;br /&gt;
;get|reading[0-9]*DeleteOnError&lt;br /&gt;
:If set to 1 this attribute causes certain readings to be deleted when the website can not be reached and the HTTP request returns an error. Internally HTTPMOD remembers which kind of operation created a reading (update, Get01, Get02 and so on). Specified readings will only be deleted if the same operation returns an error.&lt;br /&gt;
The same restrictions as for DeleteIfUnmatched apply regarding a fhem restart.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;httpVersion&lt;br /&gt;
:defines the HTTP-Version to be sent to the server. This defaults to 1.0.&lt;br /&gt;
&lt;br /&gt;
;sslVersion&lt;br /&gt;
:defines the SSL Version for the negotiation with the server. The attribute is evaluated by HttpUtils. If it is not specified, HttpUtils assumes SSLv23:!SSLv3:!SSLv2&lt;br /&gt;
&lt;br /&gt;
;sslArgs&lt;br /&gt;
:defines a list that is converted to a key / value hash and gets passed to HttpUtils. To avoid certificate validation for broken servers you can for example specify &lt;br /&gt;
:&amp;lt;code&amp;gt;attr myDevice sslArgs SSL_verify_mode,SSL_VERIFY_NONE&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;alignTime&lt;br /&gt;
:Aligns each periodic read request for the defined interval to this base time. This is typcally something like 00:00 (see the FHEM at command)&lt;br /&gt;
&lt;br /&gt;
;noShutdown&lt;br /&gt;
:pass the noshutdown flag to HTTPUtils for webservers that need it (some embedded webservers only deliver empty pages otherwise)&lt;br /&gt;
&lt;br /&gt;
;disable&lt;br /&gt;
:stop doing automatic HTTP requests while this attribute is set to 1&lt;br /&gt;
&lt;br /&gt;
;enableControlSet&lt;br /&gt;
:enables the built in set commands interval, stop, start, reread, upgradeAttributes, storeKeyValue.&lt;br /&gt;
&lt;br /&gt;
;enableCookies&lt;br /&gt;
:enables the built in cookie handling if set to 1. With cookie handling each HTTPMOD device will remember cookies that the server sets and send them back to the server in the following requests. &lt;br /&gt;
:This simplifies session magamenet in cases where the server uses a session ID in a cookie. In such cases enabling cookies should be sufficient and no sidRegex and no manual definition of a cookie header should be necessary.&lt;br /&gt;
&lt;br /&gt;
;showMatched&lt;br /&gt;
:if set to 1 then HTTPMOD will create a reading with the name MATCHED_READINGS that contains the names of all readings that could be matched in the last request as well as UNMATCHED_READINGS and LAST_REQUEST.&lt;br /&gt;
&lt;br /&gt;
;showError&lt;br /&gt;
:if set to 1 then HTTPMOD will create a reading and event with the Name LAST_ERROR that contains the error message of the last error returned from HttpUtils. &lt;br /&gt;
&lt;br /&gt;
;removeBuf&lt;br /&gt;
:if set to 1 then HTTPMOD removes the internal named buf when a HTTP-response has been received. &lt;br /&gt;
:$hash-&amp;gt;{buf} is used internally be Fhem httpUtils and in some use cases it is desireable to remove this internal after reception &lt;br /&gt;
:because it contains a very long response which looks ugly in Fhemweb.&lt;br /&gt;
&lt;br /&gt;
;timeout&lt;br /&gt;
:time in seconds to wait for an answer. Default value is 2&lt;br /&gt;
&lt;br /&gt;
;queueDelay&lt;br /&gt;
:HTTP Requests will be sent from a queue in order to avoid blocking when several Requests have to be sent in sequence. This attribute defines the delay between calls to the function that handles the send queue. It defaults to one second.&lt;br /&gt;
&lt;br /&gt;
;queueMax&lt;br /&gt;
:Defines the maximum size of the send queue. If it is reached then further HTTP Requests will be dropped and not be added to the queue&lt;br /&gt;
&lt;br /&gt;
;minSendDelay&lt;br /&gt;
:Defines the minimum time between two HTTP Requests.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* Beispiel: [[Wetter_und_Wettervorhersagen#Wetter_von_Weather_Underground|Wetter von WeatherUnderground auslesen]]&lt;br /&gt;
* Beispiel: [[Pollenflug]]&lt;br /&gt;
* Beispiel: [[HTTPMOD Beispielkonfiguration zur Anbindung einer Daikin Klimaanlage mit WLAN-Modul]]&lt;br /&gt;
* Beispiel: [[Go-eCharger|Auslesen der Information der Wallbox go-eCharger]]&lt;br /&gt;
* {{Link2Forum|Topic=17804|LinkText=Thread}} in FHEM Forum that discusses the first version of this module &lt;br /&gt;
* {{Link2Forum|Topic=29471|LinkText=Thread}} in FHEM Forum that discusses the second major version of this module &lt;br /&gt;
* {{Link2Forum|Topic=45176|LinkText=Thread}} in FHEM Forum that discusses the third major version of this module &lt;br /&gt;
* [http://perldoc.perl.org/perlretut.html Introduction to regular expressions]&lt;br /&gt;
* [http://portswigger.net/burp/ BurpSuite]: Tool (local proxy) to help analyze http traffic&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:IP Components]]&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Leere_Seite_2&amp;diff=27836</id>
		<title>Leere Seite 2</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Leere_Seite_2&amp;diff=27836"/>
		<updated>2018-09-12T20:16:13Z</updated>

		<summary type="html">&lt;p&gt;C2j2: Erfassung der Werte des go-eChargers, einer Wallbox für Elektroautos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hinweise zur schnellen Einbindung von go-eCharger (https://go-e.co/de/) per HTTP-Protokoll ==&lt;br /&gt;
&lt;br /&gt;
Voraussetzung ist, dass die HTTP-API aktiviert ist:&lt;br /&gt;
* Smartphone mit e-goCharger WLAN verbinden&lt;br /&gt;
* in &amp;quot;Cloud&amp;quot;, &amp;quot;erweiterte Einstellungen&amp;quot; das HTTP-Protokoll aktivieren&lt;br /&gt;
* &amp;quot;Neustart&amp;quot; auswählen (ohne diesen war bei mir die Box nicht zu erreichen)&lt;br /&gt;
* fertig, Smartphone kann wieder ins normale WLAN&lt;br /&gt;
&lt;br /&gt;
Dann in FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define go_eCharger HTTPMOD http://go-eCharger/status 30&lt;br /&gt;
attr go_eCharger extractAllJSON 1&lt;br /&gt;
attr go_eCharger stateFormat {sprintf(&amp;quot;%s: %s Current %d A, ETO=%d kWh&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==1?&amp;quot;ready, waiting for car&amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==2?&amp;quot;car loading&amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==3?&amp;quot;waiting for car&amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;car&amp;quot;,0)==4?&amp;quot;charge finished, but connected&amp;quot;:&amp;quot;unknown&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==1?&amp;quot;error RCCB: &amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==3?&amp;quot;error PHASE: &amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==8?&amp;quot;error NO_GROUND: &amp;quot;:\&lt;br /&gt;
ReadingsVal($name,&amp;quot;err&amp;quot;,0)==10?&amp;quot;error INTERNAL: &amp;quot;:&amp;quot;&amp;quot;,\&lt;br /&gt;
ReadingsVal($name,&amp;quot;amp&amp;quot;,0),\&lt;br /&gt;
ReadingsVal($name,&amp;quot;eto&amp;quot;,0)/10,\&lt;br /&gt;
&amp;quot;&amp;quot;\&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das dürfte so das Wichtigste sein, um die Werte auszulesen.&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=FRITZBOX&amp;diff=18027</id>
		<title>FRITZBOX</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=FRITZBOX&amp;diff=18027"/>
		<updated>2016-12-25T21:13:46Z</updated>

		<summary type="html">&lt;p&gt;C2j2: /* Bekannte Probleme / Fehlersuche */: Ergänzung zur Fehlermeldung &amp;quot;Old SID not valid anymore&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Steuerung einer Fritz!Box über Fhem&lt;br /&gt;
|ModType=d&lt;br /&gt;
|ModForumArea=FRITZ!Box&lt;br /&gt;
|ModTechName=72_FRITZBOX.pm&lt;br /&gt;
|ModOwner=tupol/Topos ({{Link2FU|5432|Forum}} / [[Benutzer Diskussion:Topos|Wiki]])}}&lt;br /&gt;
&lt;br /&gt;
Das Modul [[FRITZBOX]] ermöglicht die Steuerung einer [[AVM Fritz!Box]] und von AVM FRITZ!WLAN Repeatern durch Fhem. An Fritzboxen können sowohl Geräte abgefragt werden, auf denen FHEM selbst läuft (lokaler Modus), als auch entfernte (externe) Geräte.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
=== Remote-Zugang ===&lt;br /&gt;
Für den Remote-Zugang müssen die Module JSON:XS, LWP und SOAP::Lite installiert sein; auf einem [[Raspberry Pi]] oder unter Ubuntu z.&amp;amp;nbsp;B. mit dem Befehl&lt;br /&gt;
:&amp;lt;code&amp;gt;sudo apt-get install libjson-perl libwww-perl libsoap-lite-perl libjson-xs-perl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Teilweise ist derzeit zusätzlich die Installation der telnet Libraries erforderlich, auch wenn der Telnet-Zugang nicht genutzt werden soll. Siehe dazu den nachfolgenden Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=== Telnet ===&lt;br /&gt;
Das Modul basierte ursprünglich auf dem Zugriff auf die Fritzbox per Telnet. Ab FRITZ!OS 6.2x baut AVM den abgekündigten Telnet-Zugang sowie die webcm-Schnittstelle sukzessive zurück bzw. hat dies, je nach Firmware, schon ganz abgestellt (siehe {{Link2Forum|Topic=38586|LinkText=dieses Forenthema}}). Der zukunftssichere Zugriff auf die Fritzbox sollte also per TR-064 erfolgen. Der Vollständigkeit halber und für ältere Firmwareversionen: &lt;br /&gt;
&lt;br /&gt;
# Wer den Zugang per Telnet (noch) nutzen (kann und) möchte, muss dies zuerst freischalten. Üblicherweise durch Eingabe von #96*7* an einem direkt an der entsprechenden FritzBox angeschlosssenen Telefon&lt;br /&gt;
# Auf dem System, auf dem Fhem läuft ([[Systemübersicht#Server|Server]]) muss Telnet installiert sein; auf einem [[Raspberry Pi]] und unter Ubuntu z.&amp;amp;nbsp;B. mit dem Befehl&lt;br /&gt;
::&amp;lt;code&amp;gt;sudo apt-get install libnet-telnet-perl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
=== Erste Schritte ===&lt;br /&gt;
Zur Erstinstallation reicht ein einfaches &amp;lt;code&amp;gt;define FritzBox FRITZBOX&amp;lt;/code&amp;gt;, dieses Modul funktioniert lokal (FHEM auf Fritzbox) sowie per Fernzugriff (FHEM auf einem anderen Server im Netz, siehe nächsten Schritt).&lt;br /&gt;
&lt;br /&gt;
==== TR-064: Modul FRITZBOX für Zugriff auf einem externen Server einrichten ====&lt;br /&gt;
Für den Fernzugriff über TR-064 auf eine oder mehrere Fritzboxen und/oder einen FRITZ!WLAN Repeater sind die folgenden Schritte nötig (für jedes Gerät):&lt;br /&gt;
&lt;br /&gt;
Fritzbox definieren:&lt;br /&gt;
:&amp;lt;code&amp;gt;define FritzBox FRITZBOX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Fritzbox nicht unter &amp;lt;nowiki&amp;gt;http://fritz.box&amp;lt;/nowiki&amp;gt; erreichbar ist, IP im define setzen:&lt;br /&gt;
:&amp;lt;code&amp;gt;define FritzBox FRITZBOX 192.168.168.168&amp;lt;/code&amp;gt;&lt;br /&gt;
192.168.168.168 dabei natürlich durch die passende IP ersetzen... Alternativ kann statt der IP auch der Hostname eingegeben werden.&lt;br /&gt;
&lt;br /&gt;
Wenn (&#039;&#039;&#039;und nur wenn&#039;&#039;&#039;) das Login auf der Benutzeroberfläche der FritzBox mit User und Passwort (und nicht nur per Passwort) geschieht, den User konfigurieren:&lt;br /&gt;
:&amp;lt;code&amp;gt;attr FritzBox boxUser &#039;&#039;Benutzername&#039;&#039; &amp;lt;/code&amp;gt;&lt;br /&gt;
In der Fritzbox muss dann auch &amp;quot;Anmeldung mit FRITZ!Box-Benutzernamen und Kennwort&amp;quot; ausgewählt sein.&lt;br /&gt;
&lt;br /&gt;
Passwort konfigurieren:&lt;br /&gt;
:&amp;lt;code&amp;gt;set FritzBox password &#039;&#039;Passwort&#039;&#039;&amp;lt;/code&amp;gt;  - legt das zugehörige Passwort fest (nur einmal --&amp;gt; gehört nicht in die cfg-Datei) &lt;br /&gt;
&lt;br /&gt;
Manuelle TR-064 Kommandos erlauben (Das Auslesen der Readings per TR-064 funktioniert auch ohne dieses Attribut.):&lt;br /&gt;
:&amp;lt;code&amp;gt;attr FritzBox allowTR064Command 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Telnet: Modul FRITZBOX für Zugriff auf einem externen Server einrichten ====&lt;br /&gt;
[[Datei:Screenshot_FritzBox_TelnetUser.png|mini|300px|rechts|Anlegen des Attributs telnetUser]]&lt;br /&gt;
Bei Fernzugriff über Telnet sind weitere Schritte nötig:&lt;br /&gt;
# Telnet auf der Fritzbox freischalten (Tastenkombination #96*7* am angeschlossenen Telefon (auch FritzFon)&lt;br /&gt;
# TelnetUser definieren (wie im Screenshot gezeigt)&lt;br /&gt;
# Passwort zum Benutzer auf der Fritzbox definieren&lt;br /&gt;
&lt;br /&gt;
[[Datei:Screenshot_FritzBox_Passwort.png|mini|300px|rechts|Passwort definieren]]&lt;br /&gt;
&lt;br /&gt;
(bitte die Buttons {{Taste|set}} und {{Taste|attr}} bei der Definition der jeweiligen Einträge nicht vergessen)&lt;br /&gt;
&lt;br /&gt;
Wer stattdessen lieber das [[Konfiguration|Befehl-Eingabefeld]] verwendet:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;define FritzBox FRITZBOX&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;attr FritzBox telnetUser &#039;&#039;Benutzername&#039;&#039; &amp;lt;/code&amp;gt; - legt den Benutzer fest&lt;br /&gt;
:&amp;lt;code&amp;gt;set FritzBox password &#039;&#039;Passwort&#039;&#039; &amp;lt;/code&amp;gt; - legt das zugehörige Passwort fest&lt;br /&gt;
&lt;br /&gt;
Wer keinen User konfiguriert hat, kann das Feld &amp;quot;telnetUser&amp;quot; leer lassen.&lt;br /&gt;
&lt;br /&gt;
Wer sicher gehen möchte, dass auch tatsächlich Telnet und nicht andere Zugriffe benutzt werden, sollte außerdem noch setzen:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;attr FritzBox forceTelnetConnection 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mögliche Fehlermeldungen ===&lt;br /&gt;
Sollte schon bei &amp;lt;code&amp;gt;define FritzBox FRITZBOX&amp;lt;/code&amp;gt; die Fehlermeldung kommen, dass dieses Modul nicht existiert, dann bitte prüfen, ob Fhem auf dem aktuellen Stand ist und ggf. [[Update|aktualisieren]].&lt;br /&gt;
&lt;br /&gt;
Kommt jetzt bei der erneuten Definition die Fehlermeldung &amp;lt;code&amp;gt;Error: Perl modul Net::Telnet is missing on this system&amp;lt;/code&amp;gt; bitte wie oben schon erwähnt den Befehl &lt;br /&gt;
:&amp;lt;code&amp;gt;sudo apt-get install libnet-telnet-perl&amp;lt;/code&amp;gt; &lt;br /&gt;
direkt per Telnet/SSH auf dem FHEM-Server ausführen und neu starten.&lt;br /&gt;
Sollte alles geklappt haben, seht ihr nun eure Fritzbox und könnt diverse Einstellungen manuell vornehmen und/oder automatisch vornehmen lassen.&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
=== Define ===&lt;br /&gt;
Siehe [http://fhem.de/commandref_DE.html#FRITZBOX commandref]&lt;br /&gt;
&lt;br /&gt;
=== Attribute ===&lt;br /&gt;
Siehe commandref&lt;br /&gt;
&lt;br /&gt;
=== TR-064 ===&lt;br /&gt;
Die offizielle Programmier-Schnittstelle der Fritz!Box läuft über das Protokoll TR-064.&lt;br /&gt;
&lt;br /&gt;
mit dem Attribute&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;attr &amp;lt;device&amp;gt; allowTR064Command 1&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
kann man den Befehl&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;get &amp;lt;device&amp;gt; tr064Command &amp;lt;service&amp;gt; &amp;lt;control&amp;gt; &amp;lt;action&amp;gt; [[parameterName1 parameterValue1] ...]&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
freischalten und damit auf diese Schnittstelle zugreifen.&lt;br /&gt;
&lt;br /&gt;
AVM hat die Schnittstellenbeschreibung unter [http://avm.de/service/schnittstellen/] veröffentlicht. Diese wird jedoch nur sehr sporadisch gepflegt.&amp;lt;br&amp;gt;&lt;br /&gt;
Ein besserer Einstiegspunkt befindet sich auf der Box unter http://fritz.box:49000/tr64desc.xml.&amp;lt;br&amp;gt;&lt;br /&gt;
Die möglichen TR-064-Aktionen kann man auch über den Befehl &amp;lt;code&amp;gt;get &amp;lt;device&amp;gt; tr064ServiceList&amp;lt;/code&amp;gt; auslesen.&lt;br /&gt;
&lt;br /&gt;
Folgende Service und Controls existieren (für den get-Befehl &#039;&#039;tr064Command&#039;&#039; werden nur die fett formatierten Wörter benötigt)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!serviceType!!controlURL!!XML!!Dokument bei AVM&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;DeviceInfo:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;deviceinfo&#039;&#039;&#039;||[http://fritz.box:49000/deviceinfoSCPD.xml deviceinfoSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/deviceinfoSCPD.pdf deviceinfoSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;DeviceConfig:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;deviceconfig&#039;&#039;&#039;||[http://fritz.box:49000/deviceconfigSCPD.xml deviceconfigSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/deviceconfigSCPD.pdf deviceconfigSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;Layer3Forwarding:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;layer3forwarding&#039;&#039;&#039;||[http://fritz.box:49000//layer3forwardingSCPD.xml layer3forwardingSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/layer3forwardingSCPD.pdf layer3forwardingSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;LANConfigSecurity:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;lanconfigsecurity&#039;&#039;&#039;||[http://fritz.box:49000//lanconfigsecuritySCPD.xml lanconfigsecuritySCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/lanconfigsecuritySCPD.pdf lanconfigsecuritySCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;ManagementServer:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;mgmsrv&#039;&#039;&#039;||[http://fritz.box:49000//mgmsrvSCPD.xml mgmsrvSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/mgmsrvSCPD.pdf mgmsrvSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;Time:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;time&#039;&#039;&#039;||[http://fritz.box:49000//timeSCPD.xml timeSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/timeSCPD.pdf timeSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;UserInterface:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;userif&#039;&#039;&#039;||[http://fritz.box:49000//userifSCPD.xml userifSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/userifSCPD.pdf userifSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_VoIP:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_voip&#039;&#039;&#039;||[http://fritz.box:49000//x_voipSCPD.xml x_voipSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_voipSCPD.pdf x_voipSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_AVM-DE_Storage:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_storage&#039;&#039;&#039;||[http://fritz.box:49000//x_storageSCPD.xml x_storageSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_storageSCPD.pdf x_storageSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_AVM-DE_OnTel:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_contact&#039;&#039;&#039;||[http://fritz.box:49000//x_contactSCPD.xml x_contactSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_contactSCPD.pdf x_contactSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_AVM-DE_WebDAVClient:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_webdav&#039;&#039;&#039;||[http://fritz.box:49000//x_webdavSCPD.xml x_webdavSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_webdavSCPD.pdf x_webdavSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_AVM-DE_UPnP:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_upnp&#039;&#039;&#039;||[http://fritz.box:49000//x_upnpSCPD.xml x_upnpSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_upnp.pdf x_upnp.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_AVM-DE_RemoteAccess:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_remote&#039;&#039;&#039;||[http://fritz.box:49000/x_remoteSCPD.xml x_remoteSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_remoteSCPD.pdf x_remoteSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_AVM-DE_MyFritz:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_myfritz&#039;&#039;&#039;||[http://fritz.box:49000/x_myfritzSCPD.xml x_myfritzSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_myfritzSCPD.pdf x_myfritzSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_AVM-DE_TAM:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_tam&#039;&#039;&#039;||[http://fritz.box:49000/x_tamSCPD.xml x_tamSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_tam.pdf x_tam.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_AVM-DE_AppSetup:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_appsetup&#039;&#039;&#039;||[http://fritz.box:49000/x_homeautoSCPD.xml x_homeautoSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_appsetupSCPD.pdf x_appsetupSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;X_AVM-DE_Homeauto:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;x_homeauto&#039;&#039;&#039;||[http://fritz.box:49000/x_homeautoSCPD.xml x_homeautoSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_homeautoSCPD.pdf x_homeautoSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;WLANConfiguration:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;wlanconfig1&#039;&#039;&#039;||[http://fritz.box:49000/wlanconfigSCPD.xml wlanconfigSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/wlanconfigSCPD.pdf wlanconfigSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;WLANConfiguration:2&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;wlanconfig2&#039;&#039;&#039;||[http://fritz.box:49000/wlanconfigSCPD.xml wlanconfigSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/wlanconfigSCPD.pdf wlanconfigSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;WLANConfiguration:3&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;wlanconfig3&#039;&#039;&#039;||[http://fritz.box:49000/wlanconfigSCPD.xml wlanconfigSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/wlanconfigSCPD.pdf wlanconfigSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;Hosts:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;hosts&#039;&#039;&#039;||[http://fritz.box:49000/hostsSCPD.xml hostsSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/hostsSCPD.pdf hostsSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;LANEthernetInterfaceConfig:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;lanethernetifcfg&#039;&#039;&#039;||[http://fritz.box:49000/lanifconfigSCPD.xml lanifconfigSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/lanifconfigSCPD.pdf lanifconfigSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;LANHostConfigManagement:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;lanhostconfigmgm&#039;&#039;&#039;||[http://fritz.box:49000/lanhostconfigmgmSCPD.xml lanhostconfigmgmSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/lanhostconfigmgmSCPD.pdf lanhostconfigmgmSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;WANCommonInterfaceConfig:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;wancommonifconfig1&#039;&#039;&#039;||[http://fritz.box:49000/wancommonifconfigSCPD.xml wancommonifconfigSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/wancommonifconfigSCPD.pdf wancommonifconfigSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;WANDSLInterfaceConfig:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;wandslifconfig1&#039;&#039;&#039;||[http://fritz.box:49000/wandslifconfigSCPD.xml wandslifconfigSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/wandslifconfigSCPD.pdf wandslifconfigSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;WANDSLLinkConfig:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;wandsllinkconfig1&#039;&#039;&#039;||[http://fritz.box:49000/wandsllinkconfigSCPD.xml wandsllinkconfigSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/wandsllinkconfigSCPD.pdf wandsllinkconfigSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;WANEthernetLinkConfig:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;wanethlinkconfig1&#039;&#039;&#039;||[http://fritz.box:49000/wanethlinkconfigSCPD.xml wanethlinkconfigSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/wanethlinkconfigSCPD.pdf wanethlinkconfigSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;WANPPPConnection:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;wanpppconn1&#039;&#039;&#039;||[http://fritz.box:49000/wanpppconnSCPD.xml wanpppconnSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/wanpppconnSCPD.pdf wanpppconnSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;urn:dslforum-org:service:&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;WANIPConnection:1&#039;&#039;&#039;||/upnp/control/&#039;&#039;&#039;wanipconnection1&#039;&#039;&#039;||[http://fritz.box:49000/wanipconnSCPD.xml wanipconnSCPD.xml]||[http://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/wanipconnSCPD.pdf wanipconnSCPD.pdf]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Status-Symbol ===&lt;br /&gt;
&amp;lt;code&amp;gt;attr &amp;lt;device&amp;gt; devStateIcon .*on.*off:WLAN_on_gWLAN_off .*on.*on.*:WLAN_on_gWLAN_on WLAN..off.*:WLAN_off&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Verzeichnis www/images/default müssen die passenden Dateien &amp;quot;WLAN_on_gWLAN_off.png&amp;quot;, &amp;quot;WLAN_on_gWLAN_on.png&amp;quot; und &amp;quot;WLAN_off.png&amp;quot; liegen. Wenn die PNGs fehlen, können sie {{Link2Forum|Topic=29725|Message=318113|LinkText=hier}} heruntergeladen werden.&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiele ==&lt;br /&gt;
[[Datei:Screenshot_FritzBox1.png|mini|300px|rechts|FRITZBOX Gerät auf der Fhem Oberfläche]]&lt;br /&gt;
Sollte alles geklappt haben, seht ihr nun unter &amp;quot;Unsortiert&amp;quot; den im nebenstehenden Screenshot gezeigten Eintrag für das &amp;quot;Gerät&amp;quot; (hier mit dem Icon &amp;quot;it_router&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== TR-064 Beispiele ===&lt;br /&gt;
*Box Reboot: &amp;lt;code&amp;gt;get &amp;lt;device&amp;gt; tr064Command DeviceConfig:1 deviceconfig Reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
*Internet Reconnect: &amp;lt;code&amp;gt;get &amp;lt;device&amp;gt; tr064Command WANIPConnection:1 wanipconnection1 ForceTermination&amp;lt;/code&amp;gt;&lt;br /&gt;
*Daten eines Smart-Home-Gerätes auslesen: &amp;lt;code&amp;gt;get &amp;lt;device&amp;gt; tr064Command X_AVM-DE_Homeauto:1 x_homeauto GetGenericDeviceInfos NewIndex 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Klingel- und Sprachausgabe per TR-064 ===&lt;br /&gt;
Das geht derzeit nicht, da entsprechende Kommandos per TR-064 nicht verfügbar sind. Da Telnet sukzessive abgestellt wird, sollten sich Interessenten per Feature-Request an AVM wenden, wie {{Link2Forum|Topic=38586|LinkText=hier}} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=== Anwesenheitserkennung per regelmäßiger Abfrage über das PRESENCE Modul ===&lt;br /&gt;
Fritzboxen und die FRITZ!WLAN Repeater speichern den Status angemeldeter Geräte. Dieser Status lässt sich mittels des FRITZBOX Moduls über Readings abfragen, die das Format mac_AA_AA_AA_AA_AA_AA haben und die MAC-Adressen der jeweils angemeldeten Geräte (AA:AA:AA:AA:AA:AA) enthalten. Das Reading existiert, wenn das Gerät angemeldet ist. Wenn das Gerät abgemeldet ist, existiert es nicht mehr. Es gibt auch noch den Zwischenstatus &amp;quot;inactive&amp;quot;, der anscheinend gesetzt wird, bevor das Reading gelöscht wird.&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe des [[PRESENCE]] Moduls (vgl. [[Anwesenheitserkennung]]) kann man auf diese Weise den Anwesenheitsstatus abfragen. Anregungen dazu gibt es im zugehörigen {{Link2Forum|Topic=39433|LinkText=Forenthread}} zur Anwesenheitserkennung und in [http://heinz-otto.blogspot.de/2015/07/die-zeiten-andern-sich.html diesem  Blogpost]. Auf dieser Basis könnte eine einfache Implementierung zum Beispiel so aussehen:&lt;br /&gt;
&lt;br /&gt;
Funktion in [[99_myUtils anlegen|99_myUtils]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;perl&#039;&amp;gt;sub checkFritzMACpresent($$) {&lt;br /&gt;
  # Benötigt: Name der zu testenden Fritzbox ($Device),&lt;br /&gt;
  #           zu suchende MAC ($MAC), &lt;br /&gt;
  # Rückgabe: 1 = Gerät gefunden&lt;br /&gt;
  #           0 = Gerät nicht gefunden&lt;br /&gt;
  my ($Device, $MAC) = @_;&lt;br /&gt;
  my $Status = 0;&lt;br /&gt;
  $MAC =~ tr/:/_/;&lt;br /&gt;
  $MAC = &amp;quot;mac_&amp;quot;.uc($MAC);&lt;br /&gt;
  my $StatusFritz = ReadingsVal($Device, $MAC, &amp;quot;weg&amp;quot;);&lt;br /&gt;
  if ($StatusFritz eq &amp;quot;weg&amp;quot;) {&lt;br /&gt;
    Log 1, (&amp;quot;checkFritzMACpresent ($Device): $MAC nicht gefunden, abwesend.&amp;quot;);&lt;br /&gt;
    $Status = 0;&lt;br /&gt;
  } elsif ($StatusFritz eq &amp;quot;inactive&amp;quot;) {&lt;br /&gt;
    Log 1, (&amp;quot;checkFritzMACpresent ($Device): $MAC ist &amp;gt;inactive&amp;lt;, also abwesend.&amp;quot;);&lt;br /&gt;
    $Status = 0;&lt;br /&gt;
  } else {&lt;br /&gt;
    # Reading existiert, Rückgabewert ist nicht &amp;quot;inactive&amp;quot;, also ist das Gerät per WLAN angemeldet.&lt;br /&gt;
    Log 1, (&amp;quot;checkFritzMACpresent ($Device): $MAC gefunden, Gerät heißt &amp;gt;$StatusFritz&amp;lt;.&amp;quot;);&lt;br /&gt;
    $Status = 1;&lt;br /&gt;
  }&lt;br /&gt;
  return $Status&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nutzung dieser Funktion mit dem PRESENCE Modul definieren:&lt;br /&gt;
:&amp;lt;code&amp;gt;define &amp;lt;Name&amp;gt; PRESENCE function {checkFritzMACpresent(&amp;quot;Fritzbox&amp;quot;,&amp;quot;AA:BB:CC:DD:EE:FF&amp;quot;)}  60 60&amp;lt;/code&amp;gt;&lt;br /&gt;
wobei&lt;br /&gt;
*&amp;lt;Name&amp;gt; ein beliebig zu wählender Name für die PRESENCE-Funktion ist,&lt;br /&gt;
*Fritzbox der Name ist, mit dem ihr die abzufragende Fritzbox als FRITZBOX definiert habt,&lt;br /&gt;
*AA:BB:CC:DD:EE:FF die MAC-Adresse des gesuchten Geräts ist.&lt;br /&gt;
* &amp;quot;60 60&amp;quot; sagt, dass der Anwesenheitsstatus im 60-Sekunden-Takt abgefragt wird. Das macht natürlich nur Sinn, wenn ihr mit &amp;lt;code&amp;gt;attr Fritzbox INTERVAL 60&amp;lt;/code&amp;gt; den Abfrageinterval bei der Fritzbox auch entsprechend hochgesetzt habt. Der Standard ist 300.&lt;br /&gt;
* &amp;quot;Log 1&amp;quot; führt immer zum Loggen. Das ist zum Einrichten praktisch, ohne dass man gleich für das ganze Modul oder ganz FHEM &amp;lt;code&amp;gt;attr &amp;lt;device&amp;gt; verbose 5&amp;lt;/code&amp;gt; setzen muss. Wenn es läuft, können die &amp;quot;Log 1&amp;quot;-Zeilen gelöscht, auskommentiert (# an den Zeilenanfang) oder in &amp;quot;Log 5&amp;quot; geändert werden.&lt;br /&gt;
&lt;br /&gt;
=== Anwesenheitserkennung über mehrere Fritzboxen oder AVM Repeater und Fritzbox ===&lt;br /&gt;
Existiert ein AVM Repeater im Netzwerk, kann der als eigenständiges Gerät mit FRITZBOX definiert werden. WLAN Geräte an der Fritzbox werden in der Instanz der Fritzbox gelistet und WLAN Geräte am Repeater in der Repeater Instanz. Um trotzdem die Anwesenheit im Netzwerk einfach zu erkennen, muss die Subroutine in 99_myUtils.pm abgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
Existiert eine zweite Fritzbox im Accesspointmodus, werden die WLAN Geräte im Netzwerk alle in der Hauptfritzbox an einem LAN Anschluss gelistet. D.h. man sieht an der Hauptfritzbox nicht, dass sie im WLAN sind. Eine zweite Instanz mit dem FRITZBOX Modul muss wegen der Anwesenheitserkennung nicht gemacht werden. Die folgende Routine kann aber universell eingesetzt werden, unabhängig von der Anzahl der FRITZBOX Instanzen. Wer mitloggen will, kann das analog zur obigen Routine einbauen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;perl&#039;&amp;gt;sub checkAllFritzMACpresent($) {&lt;br /&gt;
  # Benötigt: nur die zu suchende MAC ($MAC), &lt;br /&gt;
  # Es werden alle Instanzen vom Type FRITZBOX abgefragt&lt;br /&gt;
  #&lt;br /&gt;
  # Rückgabe: 1 = Gerät gefunden&lt;br /&gt;
  #           0 = Gerät nicht gefunden&lt;br /&gt;
  my ($MAC) = @_;&lt;br /&gt;
  # Wird in keiner Instanz die MAC Adresse gefunden bleibt der Status 0&lt;br /&gt;
  my $Status = 0;&lt;br /&gt;
  $MAC =~ tr/:/_/;&lt;br /&gt;
  $MAC = &amp;quot;mac_&amp;quot;.uc($MAC);&lt;br /&gt;
  my @FBS = devspec2array(&amp;quot;TYPE=FRITZBOX&amp;quot;);&lt;br /&gt;
    foreach( @FBS ) {&lt;br /&gt;
		my $StatusFritz = ReadingsVal($_, $MAC, &amp;quot;weg&amp;quot;);&lt;br /&gt;
		if ($StatusFritz eq &amp;quot;weg&amp;quot;) {&lt;br /&gt;
		} elsif ($StatusFritz eq &amp;quot;inactive&amp;quot;) {&lt;br /&gt;
		} else {&lt;br /&gt;
		  # Reading existiert, Rückgabewert ist nicht &amp;quot;inactive&amp;quot;, also ist das Gerät am Netzwerk angemeldet.&lt;br /&gt;
		  $Status = 1;&lt;br /&gt;
		}&lt;br /&gt;
    }&lt;br /&gt;
  return $Status&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da hiermit nach allen Instanzen mit dem TYPE=FRITZBOX durchsucht wird, braucht der Name der Fritzbox nicht angegeben werden.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;code&amp;gt;define &amp;lt;Name&amp;gt; PRESENCE function {checkAllFritzMACpresent(&amp;quot;AA:BB:CC:DD:EE:FF&amp;quot;)}  60 60&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weitere Hinweise zu komplexeren Abfragen mehrere Boxen auf einmal etc. findet ihr auch im diesem {{Link2Forum|Topic=39433|LinkText=Forenthread}}.&lt;br /&gt;
&lt;br /&gt;
=== Anwesenheitserkennung per Notify ===&lt;br /&gt;
Der von Fritzboxen und Fritz!WLAN Repeatern gespeicherte Status zum Status angemeldeter Geräte lässt sich (statt per PRESENCE, s.o.) auch per [[notify]] anfragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;define &amp;lt;Name&amp;gt; notify Fritzbox:mac_AA_BB_CC_DD_EE_FF:.* {&lt;br /&gt;
  if (ReadingsVal(&amp;quot;Fritzbox&amp;quot;, &amp;quot;mac_AA_BB_CC_DD_EE_FF&amp;quot;, &amp;quot;inactive&amp;quot;) eq &amp;quot;inactive&amp;quot;) &lt;br /&gt;
  {&lt;br /&gt;
    fhem(&amp;quot;set anwesend_smartphone absent&amp;quot;);&lt;br /&gt;
  } &lt;br /&gt;
  else &lt;br /&gt;
  {&lt;br /&gt;
    fhem(&amp;quot;set anwesend_smartphone present&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweise:&lt;br /&gt;
* &amp;lt;code&amp;gt;fhem(&amp;quot;set anwesend_smartphone absent&amp;quot;);&amp;lt;/code&amp;gt; ist nur ein Beispiel, das einen Dummy auf den Status &amp;quot;absent&amp;quot; bzw. &amp;quot;present&amp;quot; setzt. Man kann hier natürlich auch gleich entsprechende Aktionen durchführen. Wer das Beispiel übernehmen möchte, sollte den Dummy vorher definieren (&amp;lt;code&amp;gt;define anwesend_smartphone dummy&amp;lt;/code&amp;gt;).&lt;br /&gt;
* mac_AA_BB_CC_DD_EE_FF ist die MAC-Adresse des gesuchten Geräts.&lt;br /&gt;
* &amp;quot;Fritzbox&amp;quot; ist der Name, unter dem die Fritzbox als FRITZBOX-Modul definiert wurde.&lt;br /&gt;
* Das Notify funktioniert, weil Geräte, wenn sie sich abgemeldet haben, erst den Status &amp;quot;inactive&amp;quot; erhalten. Ist das Gerät ganz abgemeldet, verschwindet das mac_.*-Reading. Dabei löst das Notify nicht mehr aus. Da das mac-.*-Reading aber vorher auf &amp;quot;inactive&amp;quot; stand, wurde die Abwesend-Aktion schon ausgeführt.&lt;br /&gt;
* Damit der Notify nicht andauernd losgeht, sollte man mittels &amp;lt;code&amp;gt;attr Fritzbox [[event-on-change-reading]] mac_AA_BB_CC_DD_EE_FF&amp;lt;/code&amp;gt; Events nur auslösen, wenn sich der Status des Gerätes ändert. Will man mehrere Geräte abfragen, sollte man &amp;lt;code&amp;gt;attr Fritzbox event-on-change-reading mac_AA_BB_CC_DD_EE_FF,mac_GG_HH_II_JJ_KK_LL&amp;lt;/code&amp;gt; setzen, damit bei der Änderung jedes Readings ein Event ausgelöst wird.&lt;br /&gt;
&lt;br /&gt;
=== Vergleich Anwesenheitserkennung PRESENCE/Notify ===&lt;br /&gt;
Die Anwesenheitserkennung per regelmäßiger PRESENCE-Abfrage hat den Vorteil, dass sie im Turnus der regelmäßigen Abfragen immer einen aktuellen Status produziert. Sie hat dafür den Nachteil, dass die PRESENCE-Funktionen regelmäßig abgearbeitet werden müssen, auch wenn sich gar nichts ändert. Außerdem aktualisiert sich der Status nicht sofort, sondern erst bei der nächsten regelmäßigen Abfrage. Durch häufiges Abfragen kann dieser Nachteil verringert werden (bei entsprechend höherer Systemlast).&lt;br /&gt;
&lt;br /&gt;
Die Anwesenheitserkennung per Notify hat den Vorteil, dass ein sich ändernder Status sofort abgebildet wird. Ändert sich kein Status, werden keine Routinen ausgeführt, was die Systemlast gering hält. Der Nachteil ist, dass - z.B. nach einem Systemstart - die entsprechende Aktion erst bei einer Änderung des Status ausgeführt wird. D.h. ist das zu testende Gerät anwesend, wird dann FHEM beendet, das Gerät entfernt und FHEM wieder gestartet, ist der Status in FHEM immer noch &amp;quot;anwesend&amp;quot;. Da das Reading für das Gerät nicht existiert, wird darauf auch erst wieder ein Notify ausgeführt, wenn sich der Status des Geräts wieder ändert, d.h. es wieder ankommt. Bis dahin ist der Status im System falsch. &lt;br /&gt;
Der Nachteil des Notify kann verringert werden, wenn man statt &amp;lt;code&amp;gt;attr Fritzbox event-on-change-reading mac_AA_BB_CC_DD_EE_FF&amp;lt;/code&amp;gt; ein &amp;lt;code&amp;gt;attr Fritzbox [[event-on-update-reading]] mac_AA_BB_CC_DD_EE_FF&amp;lt;/code&amp;gt; setzt. Das erhöht allerdings die Systemlast und funktioniert auch nur für den Status &amp;quot;anwesend&amp;quot;. Bei &amp;quot;abwesend&amp;quot; ist kein Reading vorhanden, so dass auch event-on-update-reading nicht ausgeführt wird.&lt;br /&gt;
Eine weitere Möglichkeit, den Nachteil der Notify-Methode auszugleichen, ist, die Statusabfrage beim Systemstart einmal manuell auszuführen, durch ein notify auf &amp;quot;GLOBAL:initialized&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
global:INITIALIZED {&lt;br /&gt;
  Reset_Variables;&lt;br /&gt;
  if (ReadingsVal(&amp;quot;Fritzbox&amp;quot;, &amp;quot;mac_AA_BB_CC_DD_EE_FF&amp;quot;, &amp;quot;inactive&amp;quot;) eq &amp;quot;inactive&amp;quot;) {&lt;br /&gt;
    fhem(&amp;quot;set anwesend_smartphone absent&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    fhem(&amp;quot;set anwesend_smartphone present&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Das hilft allerdings nur beim Systemstart. Nicht, wenn FHEM aufgrund irgendwelcher Hänger eine Aktualisierung des Status verpasst hat.&lt;br /&gt;
&lt;br /&gt;
=== userReadings per get tr064Command ===&lt;br /&gt;
Um dem Gerätewert &amp;lt;userReadingName&amp;gt; den Wert von &amp;lt;VariabelName&amp;gt; aus der Rückgabe des get-Befehls &#039;&#039;tr064Command&#039;&#039; zuzuordnen&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attr &amp;lt;device&amp;gt; userReadings &amp;lt;userReadingName&amp;gt; {my $resp=fhem(&amp;quot;get &amp;lt;device&amp;gt; tr064Command &amp;lt;service&amp;gt; &amp;lt;control&amp;gt; &amp;lt;action&amp;gt; [[&amp;lt;argName1&amp;gt; &amp;lt;argValue1&amp;gt;] ...]&amp;quot;,1);;$resp =~/\&#039;&amp;lt;VariabelName&amp;gt;\&#039; =&amp;gt; &#039;(.*)&#039;/;;return $1;;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Beispielsweise&lt;br /&gt;
&amp;lt;pre&amp;gt;attr Fritzbox userReadings urMobilteil_1 {my $resp=fhem(&amp;quot;get Fritzbox tr064Command X_AVM-DE_OnTel:1 x_contact GetDECTHandsetInfo NewDectID 1&amp;quot;,1);;$resp =~/&#039;NewHandsetName&#039; =&amp;gt; &#039;(.*)&#039;/;;return $1;;},&lt;br /&gt;
        urDownstreamDSLRate {my $resp=fhem(&amp;quot;get Fritzbox tr064Command WANDSLInterfaceConfig:1 wandslifconfig1 GetInfo&amp;quot;,1);;$resp =~/&#039;NewDownstreamCurrRate&#039; =&amp;gt; &#039;(.*)&#039;/;;return $1;;},&lt;br /&gt;
        urUpstreamDSLRate {my $resp=fhem(&amp;quot;get Fritzbox tr064Command WANDSLInterfaceConfig:1 wandslifconfig1 GetInfo&amp;quot;,1);;$resp =~/&#039;NewUpstreamCurrRate&#039; =&amp;gt; &#039;(.*)&#039;/;;return $1;;}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Klingelton-Einstellung und Abspielen von Sprachnachrichten bei Fritz!OS-Versionen &amp;gt;6.24 ===&lt;br /&gt;
Wenn die Fritzbox weder die Telnet- noch die webcmd-Schnittstelle hat, kann der Klingelton der Fritz!Fons nicht mehr verstellt und auch keine Sprachnachricht über ein Fritz!Fon ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Es gibt eine Behelfslösung über das Attribut &#039;&#039;useGuiHack&#039;&#039;. Dadurch wird eine Eingabe in die WebGUI der Fritzbox simuliert. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG&#039;&#039;&#039;: Vor allem nach einem Update der FritzBox kann es durch dieses Attribut zu ungewolltem Verstellen von Werten in der Fritzbox kommen.&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung der ring-Parameter &amp;quot;play:&amp;quot; und &amp;quot;say:&amp;quot; wird die abzuspielende URL in die M3U-Datei, die unter dem Internal &#039;&#039;M3U_LOCAL&#039;&#039; steht, eingetragen.&amp;lt;br&amp;gt; &lt;br /&gt;
Standardmäßig wird versucht, diese Datei im image-Verzeichnis von FHEM abzulegen. Diese kann dann vom Fritz!Fon über [[FHEMWEB]] abgespielt werden (IP-Freigaben beachten). Direkt nach dem ersten Anlegen der m3u-Datei kennt [[FHEMWEB]] diese noch nicht, daher bitte entweder &#039;&#039;set &amp;lt;webdevice&amp;gt; rereadicons&#039;&#039; ausführen oder FHEM neu starten.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aufgrund der Beschränkungen von [[FHEMWEB]] oder auch bei Authentifizierungsanforderungen ist es empfehlenswert, die Datei über das Attribute &#039;&#039;m3uFileLocal&#039;&#039; selber vorzugeben. Am besten auf einem Webserver, der auf dem FHEM-Server läuft und dessen Seiten-Verzeichnis durch FHEM beschreibbar ist.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel: &amp;lt;code&amp;gt;attr Fritzbox m3uFileLocal /var/www/mp3/Fritzbox.m3u&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In dem Radioeintrag &#039;&#039;FHEM&#039;&#039; muss dann &#039;&#039;&#039;auf der FritzBox&#039;&#039;&#039;, die &#039;&#039;&#039;Web&#039;&#039;&#039;-Adresse der entsprechenden Datei eingetragen werden. Dieser Sender sollte zu Testzwecken dann auch einmal am Fritz!Fon von Hand gestartet werden.&amp;lt;br&amp;gt;&lt;br /&gt;
Das Modul versucht, beim Start die einzutragende Radio-URL im image-Verzeichnis selber zu ermitteln (IP-Freigabe beachten). Gelingt dies, so steht diese im Internal &#039;&#039;M3U_URL&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Ring auf mehreren Telefonen gleichzeitig ===&lt;br /&gt;
&lt;br /&gt;
Damit mehrere Telefone per ring gleichzeitig Klingel, muss in der Fritzbox eine Rufgruppe definiert werden.&lt;br /&gt;
Sollte eine Türsprechanlage schon in Benutzung sein, kann die eventuell hierfür bereits eingerichtete Gruppe verwendet werden.&lt;br /&gt;
Das anlegen der Gruppe erfolgt wie in folgender AVM Anleitung erledigt werden. [http://http://avm.de/service/fritzbox/fritzbox-7390/wissensdatenbank/publication/show/1148_Interne-Rufgruppe-in-FRITZ-Box-einrichten-Gruppenruf/ AVM Interne Rufgruppe anlegen]&lt;br /&gt;
&lt;br /&gt;
Es muss eine Kurzwahl bei der Gruppe zwingend hinterlegt sein.&lt;br /&gt;
Danach kann mit folgendem Beispiel Code gearbeitet werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;set FritzBox ring 791 15 show:Türklingel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Name des Devices, Rufgruppen Nummer, Länge und gezeigter Text auf das gewünschte anpassen.&lt;br /&gt;
&lt;br /&gt;
== Bekannte Probleme / Fehlersuche ==&lt;br /&gt;
=== Modul bleibt im Status &amp;quot;Check APIs&amp;quot; hängen===&lt;br /&gt;
Im Log steht die Meldung: &amp;quot;Error: Timeout when reading Fritz!Box data.&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Mögliche Ursache: Nutzung des FHEM-Befehls [[FHEM_Command_Beispiele#rereadcfg|rereadcfg]]. Dieser verträgt sich nicht mit dem Modul &amp;quot;blocking.pm&amp;quot;, das für parallel laufende FHEM-Prozesse genutzt wird.&lt;br /&gt;
&lt;br /&gt;
Abhilfe schafft ein Neustart &amp;lt;code&amp;gt;shutdown restart&amp;lt;/code&amp;gt; oder das Einfügen eines zusätzlichen, lokalen Telnet-Ports z.B. durch &amp;lt;code&amp;gt;define tPortLocal telnet 7073&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nachtschaltung Doppel-WLAN ===&lt;br /&gt;
Beim Abschalten des WLAN über das Modul wird (über TR064) zuerst das 2.4 GHz und dann das 5 GHz WLAN ausgeschaltet. Bei der gleichzeitigen Nutzung der WLAN-Nachtschaltung (Anschalten über das Fritz!OS) wird dann jedoch nur noch das 5 GHz WLAN wieder angeschaltet. Die Box interpretiert den TR064-Befehl anscheinend als ein komplettes Abwählen des 2.4 GHz WLAN.&lt;br /&gt;
&lt;br /&gt;
Abhilfe schafft hier nur ein notify auf das 5 GHz WLAN mit einem nachträglichem Anschalten des 2.4 GHz WLAN.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann das Ausschalten des WLANs nicht direkt über TR064-Kommandos, sondern über einen indirekten Weg erfolgen: über TR064 ein set call abzusetzen und hier den Tastencode zum Ausschalten des WLANs einzugeben, bei einer FritzBox 7490 wäre dies z. B. #96*0*. &lt;br /&gt;
Schaltet man über diese Methode das WLAN aus, kann es über die Nachtschaltung wieder automatisch auf beiden Frequenzen angeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Kabelboxen ===&lt;br /&gt;
Bei Fritz!Boxen für den Kabelanschluss (z.B. Kabel Deutschland) scheint neben Telnet auch die TR064-API nicht zu funktionieren. Vermutlich wurde die API von AVM auf Betreiberwunsch deaktiviert, da man sonst Dinge ändern kann, die das gesamte Kabelnetz stören können.&lt;br /&gt;
&lt;br /&gt;
=== Wenn&#039;s nicht klingelt ===&lt;br /&gt;
Das Klingeln erfolgt über die Wählhilfe. Eventuell muss über die Weboberfläche der Fritz!Box ein anderer Port eingestellt werden. Der aktuelle steht in &amp;quot;box_stdDialPort&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== TR064-Transport-Error: 500 Can&#039;t connect to ...:49443 (certificate verify failed) ===&lt;br /&gt;
Eventuell hilft es, die Perl Module Net::HTTPS, Net::SSL und IO::Socket::SSL zu aktualisieren.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Error: Old SID not valid anymore.&amp;quot; nach Erlauben von IPv6 auf der Fritzbox ===&lt;br /&gt;
Ohne hier den genauen Grund zu kennen - helfen tut die Angabe der IPv4-Adresse, also statt &amp;lt;code&amp;gt;define FritzBox FRITZBOX&amp;lt;/code&amp;gt; dann &amp;lt;code&amp;gt;define FritzBox FRITZBOX &amp;lt;IP&amp;gt;&amp;lt;/code&amp;gt; (z.B. &amp;lt;code&amp;gt;define FritzBox FRITZBOX 192.168.10.1&amp;lt;/code&amp;gt;), so dass  das Modul nicht über IPv6 geht.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* {{Link2Forum|Topic=29725|LinkText=Forenthread}} zu diesem Modul&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:FritzBox]] &lt;br /&gt;
&amp;lt;!-- (Modulkategorie wird automatisch gesetzt) --&amp;gt;&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=RFXtrx&amp;diff=17642</id>
		<title>RFXtrx</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=RFXtrx&amp;diff=17642"/>
		<updated>2016-12-01T17:32:18Z</updated>

		<summary type="html">&lt;p&gt;C2j2: /* Decodierung der Steckdosen-Zuordnung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Fhem unterstützt viele durch einen &#039;&#039;&#039;RFXtrx&#039;&#039;&#039;433 Transceiver erreichbare Geräte durch eigene Module.&lt;br /&gt;
&lt;br /&gt;
== Übersicht ==&lt;br /&gt;
[[File:Rfxtrx433.png|500px|right]]&lt;br /&gt;
&lt;br /&gt;
RFXtrx433 ist ein Transceiver (Funkempfänger und Funksender) mit USB-Anschluss für den Frenzbereich 433,92 MHz. Die Stromversorgung erfolgt über USB.  Das Gerät hat einen FTDI-FT232R-USB-Interface-Chip installiert. Um RFXtrx433 nutzen zu können, muss das Betriebssystem einen entsprechenden Treiber für diesen Chip haben. Genutzt wird RFXtrx433 von Anwendern mit FHEM unter Linux, Fritzbox 7390 oder Windows.&lt;br /&gt;
&lt;br /&gt;
Mit der mitgelieferten Firmware können viele Funksensoren in diesem Frequenzbereich empfangen werden und es ist möglich bestimmte Protokolle auch zu senden. Die unterstützten Protokolle sind von der installierten Firmware abhängig, die über das Windows-Programm [http://www.rfxcom.com/Downloads RFXflash] aktualisiert werden kann. Die neueste Firmware ist unter [http://www.rfxcom.com/Downloads http://www.rfxcom.com/Downloads] zu finden.&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen zu den von diesem Transceiver verfügbaren Protokolle beim Hersteller unter [http://www.rfxcom.com www.rfxcom.com]. Da der Hersteller die Anzahl der Geräte ständig aktualisiert und die FHEM-Treiber in der Freizeit des Autors geschrieben werden, sind in den FHEM-Treibern nur eine Untermenge implementiert. Sollte ein Gerät/Protokoll fehlen, das die Firma RFXCOM unterstützt, können Sie im [http://forum.fhem.de/ FHEM-Forum] in der Untergruppe RFXTRX nachfragen, ob dieses implementiert werden kann.&lt;br /&gt;
&lt;br /&gt;
TRXtrx433 wird derzeit von FHEM mit den Modulen TRX, TRX_LIGHT, TRX-SECURITY und TRX_WEATHER für eine Reihe von Protokollen unterstützt.&lt;br /&gt;
&lt;br /&gt;
Nachfolgend werden nur Geräte aufgezeigt, die bei der Erstellung dieses WIKI-Eintrages eingepflegt werden.&lt;br /&gt;
&lt;br /&gt;
== FHEM-Modul: TRX_WEATHER ==&lt;br /&gt;
Dieses Modul unterstützt Wettersensoren, insbesondere Sensoren des Herstellers Oregon-Scientific. Unter [http://www.rfxcom.com/oregon.htm Wetter-Sensoren] finden Sie eine Liste der von der RFXtrx433-Firmware unterstützten Wetter-Sensoren (Oregon-Scientific, Cresta, La Crosse, TFA, UPM, ...). Das FHEM-Modul TRX_WEATHER implementiert derzeit den Empfang folgender Sensorentypen und Sensoren:&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Temperatursensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;THR128&amp;quot;: Oregon-Scientific THR128/138, THC138&lt;br /&gt;
* &amp;quot;THGR132N&amp;quot;: Oregon-Scientific THC238/268,THN132,THWR288,THRN122,THN122,AW129/131&lt;br /&gt;
* &amp;quot;THWR800&amp;quot;: Oregon-Scientific THWR800&lt;br /&gt;
* &amp;quot;RTHN318&amp;quot;: Oregon-Scientific RTHN318&lt;br /&gt;
* &amp;quot;TS15C&amp;quot;: TS15C&lt;br /&gt;
* &amp;quot;VIKING_02811&amp;quot; : Viking 02811&lt;br /&gt;
* &amp;quot;WS2300&amp;quot; : La Crosse WS2300&lt;br /&gt;
* &amp;quot;RUBICSON&amp;quot; : RUBiCSON&lt;br /&gt;
* &amp;quot;TFA_303133&amp;quot; : TFA 30.3133&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Temperatur-/Luftffeuchtigkeitssensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;THGR228N&amp;quot;: Oregon-Scientific THGN122/123, THGN132, THGR122/228/238/268 [[File:Thgr228n.png|92px|right|thumb|THGR228N]]&lt;br /&gt;
* &amp;quot;THGR810&amp;quot;: Oregon-Scientific THGR810&lt;br /&gt;
* &amp;quot;RTGR328&amp;quot;: Oregon-Scientific RTGR328&lt;br /&gt;
* &amp;quot;THGR328&amp;quot;: Oregon-Scientific THGR328&lt;br /&gt;
* &amp;quot;WTGR800_T&amp;quot;: Oregon-Scientific WTGR800&lt;br /&gt;
* &amp;quot;THGR918&amp;quot;: Oregon-Scientific THGR918, THGRN228, THGN500&lt;br /&gt;
* &amp;quot;TFATS34C&amp;quot;: TFA TS34C (Kat. Nr. 30.3150)&lt;br /&gt;
* &amp;quot;WT450H&amp;quot;: UPM WT450H&lt;br /&gt;
* &amp;quot;TX3_T&amp;quot;: LaCrosse TX3, TX4, TX17&lt;br /&gt;
[[File:TX3TH.jpg|92px|right|thumb|TX3TH]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Nicht unterstützt werden von der RFXCOM-Firmware:&#039;&#039;&#039; TFA 30.3166&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Temperatur-/Luftffeuchtigkeits-/Luftdrucksensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;BTHR918&amp;quot;: Oregon-Scientific BTHR918&lt;br /&gt;
* &amp;quot;BTHR918N&amp;quot;: Oregon-Scientific/Huger BTHR918N, BTHR968 [[File:Bthr918n.png|96px|right|thumb|BTHR918N]]&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Regensensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;RGR918&amp;quot;: Oregon-Scientific RGR126/682/918&lt;br /&gt;
* &amp;quot;PCR800&amp;quot;: Oregon-Scientific PCR800&lt;br /&gt;
* &amp;quot;TFA_RAIN&amp;quot;: TFA-Regensensor (Kat. Nr. 30.3148)&lt;br /&gt;
* &amp;quot;RG700&amp;quot;: UPM RG700&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Windsensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;WTGR800_A&amp;quot;: Oregon-Scientific WTGR800&lt;br /&gt;
* &amp;quot;WGR800_A&amp;quot;: Oregon-Scientific WGR800&lt;br /&gt;
* &amp;quot;WGR918&amp;quot;: Oregon-Scientific STR918, WGR918&lt;br /&gt;
* &amp;quot;TFA_WIND&amp;quot;: TFA-Windsensor (Kat. Nr. 30.3149)&lt;br /&gt;
* &amp;quot;WDS500&amp;quot; : UPM WDS500&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;UV-Sensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;UVN128&amp;quot;: Oregon UVN128, UV138&lt;br /&gt;
* &amp;quot;UVN800&amp;quot;: Oregon UVN800&lt;br /&gt;
* &amp;quot;TFA_UV&amp;quot;: TFA_UV-Sensor&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Waagen&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;BWR101&amp;quot;: Oregon Scientific BWR101&lt;br /&gt;
* &amp;quot;GR101&amp;quot;: Oregon Scientific GR101&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Energiesensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;CM160&amp;quot;: OWL CM119 und CM160&lt;br /&gt;
* &amp;quot;CM180&amp;quot;: OWL CM180&lt;br /&gt;
&lt;br /&gt;
Der Autor des Module setzt derzeit folgende Sensoren ein:&lt;br /&gt;
&lt;br /&gt;
* Oregon Scientific: BTHR918, BTHR918N, PCR800, RGR918, THGR228N, THR128, THWR288A, WTGR800, WGR918&lt;br /&gt;
&lt;br /&gt;
Von Nutzern wurde die Funktion folgender weiterer Sensoren gemeldet:&lt;br /&gt;
&lt;br /&gt;
* Oregon Scientific GR101&lt;br /&gt;
* Oregon Scientific RTGR-328 (T/H)&lt;br /&gt;
* Honeywell TF-ATS34C (T/H)&lt;br /&gt;
* TFA Regensender 433 MHz, Kat. Nr. 30.3148, siehe [http://tfa-dostmann.de/index.php?id=57 TFA]&lt;br /&gt;
* TFA Windsender 433 MHz, Kat. Nr. 30.3149, siehe [http://tfa-dostmann.de/index.php?id=57 TFA]&lt;br /&gt;
* TFA T/H-Sender 433 MHz, Kat. Nr. 30.3150, siehe [http://tfa-dostmann.de/index.php?id=57 TFA]&lt;br /&gt;
* OWL CM160&lt;br /&gt;
&lt;br /&gt;
=== FAQ: Wie bringe ich FHEM dazu nicht alle paar Sekunden den Zustand der Sensoren zu loggen? ===&lt;br /&gt;
&lt;br /&gt;
Den ein oder anderen hat es schon genervt, dass die Oregon-Sensoren sehr gesprächig sind und damit das Filelog sehr groß wird.&lt;br /&gt;
&lt;br /&gt;
Abhilfe: Hierzu kann man event-min-interval verwenden, um festzulegen, dass Events nur alle x Minuten generiert werden. event-on-change-reading kann man verwenden, dass Änderungen trotzdem sofort bemerkt werden.&lt;br /&gt;
&lt;br /&gt;
Nachfolgend wird ein Oregon-Sensor BTHR918 so konfiguriert, dass er nur alle 10 Minuten loggt, aber beim State die Änderungen sofort geloggt werden.&lt;br /&gt;
&lt;br /&gt;
 define Alte_Garage TRX_WEATHER BTHR918&lt;br /&gt;
 attr Alte_Garage event-min-interval state:600&lt;br /&gt;
 attr Alte_Garage event-on-change-reading state&lt;br /&gt;
 attr Alte_Garage event-on-update-reading .*&lt;br /&gt;
&lt;br /&gt;
Damit man nicht alles loggt, kann man das Logging auf die Zeilen beschränken, die mit T: beginnen:&lt;br /&gt;
&lt;br /&gt;
 define FileLog_Alte_Garage FileLog /var/log/fhem/Alte_Garage-%Y.log Alte_Garage:T\x3a.*&lt;br /&gt;
 attr FileLog_Alte_Garage logtype temp4press8:Temp/Press,temp4hum6dew10:Temp/Hum,text&lt;br /&gt;
&lt;br /&gt;
Damit hat man dann folgendes im Log:&lt;br /&gt;
&lt;br /&gt;
 2013-08-27_12:21:29 Alte_Garage T: 19.9 H: 69 P: 1005 BAT: low&lt;br /&gt;
 2013-08-27_12:31:37 Alte_Garage T: 19.9 H: 69 P: 1005 BAT: low&lt;br /&gt;
 2013-08-27_12:41:45 Alte_Garage T: 19.9 H: 69 P: 1005 BAT: low&lt;br /&gt;
 2013-08-27_12:47:27 Alte_Garage T: 20 H: 68 P: 1005 D: BAT: low&lt;br /&gt;
 2013-08-27_12:57:35 Alte_Garage T: 20 H: 68 P: 1005 D: BAT: low&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wie man sieht, wird normalerweise alle 10 Minuten geloggt. Um 12:47:27 hat sich die Temperatur verändert und damit wurde ausserhalb der Reihe sofort ein Event generiert.&lt;br /&gt;
&lt;br /&gt;
Ja, stimmt, ich muss noch die Batterie des Sensors wechseln (BAT: low) ;-)&lt;br /&gt;
&lt;br /&gt;
== FHEM-Modul: TRX_SECURITY ==&lt;br /&gt;
Empfängt Security-Sensoren der Protokolle X10-Security, KD101 und Visonic. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KD101 kompatible Rauchmelder&#039;&#039;&#039;&lt;br /&gt;
Es wurden folgende KD101-Versionen gemeldet, die mit RXFtrx433 empfangen werden können:&lt;br /&gt;
&lt;br /&gt;
* KD101LD&lt;br /&gt;
* KD101LA&lt;br /&gt;
* Flamingo FA20RF&lt;br /&gt;
* Elro RM150RF&lt;br /&gt;
* Unitec 46779&lt;br /&gt;
&lt;br /&gt;
Die Rauchmelder KD101 (KD101LD, KD101LA, Flamingo FA20RF, Elro RM150RF) haben folgendes Verhalten:&lt;br /&gt;
&lt;br /&gt;
* Wenn der KD101 selbst Rauch feststellt, kann man diesen Alarm über Funk nicht stoppen. Er sendet &amp;quot;alert&amp;quot; über Funk.&lt;br /&gt;
* Wenn man &amp;quot;alarm&amp;quot; über Funk an einen Rauchmelder sendet, dauert der Alarm nur wenige Sekunden. Für einen dauerhaften Alarm muss man also &amp;quot;alert&amp;quot; immer wieder senden.&lt;br /&gt;
* Wenn man die KD101 pairt, bekommen alle gepairten KD101 dieselbe ID.&lt;br /&gt;
* Wenn einer Rauch erkennt, triggert er alle KD101 mit derselben ID (also die gepairten).&lt;br /&gt;
* Nach Drücken der Taste &amp;quot;Test&amp;quot; am Rauchmelder sendet dieser &amp;quot;alert&amp;quot;. Dadurch wird per autocreate der Rauchmelder angelegt.&lt;br /&gt;
* Ein KD101 sendet kein Keepalive-Signal. Man kann also nur testen, ob ein Rauchmelder noch funktioniert, indem man die Test-Taste drückt.&lt;br /&gt;
&lt;br /&gt;
Mittels RFXtrx433 kann man die Befehle &amp;quot;alert&amp;quot; und &amp;quot;pair&amp;quot; an einen Rauchmelder senden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
* set TRX_KD101_a5ca00 alert&lt;br /&gt;
&lt;br /&gt;
Dies sendet den panic-Befehl an den Rauchmelder. Damit hört man ca. 3 Sekunden lang den nervigen Ton des Rauchmelders. Wer diesen länger haben will, muss das set nach ca. 3 Sekunden erneut auslösen.&lt;br /&gt;
Wer man also ein &amp;quot;set DEVICE alert&amp;quot; an einen Rauchmelder schickt, der mit anderen gepairt ist, dann wird der Alarm bei allen gepairten Rauchmeldern ausgelöst.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;X10-Security-Sensoren&#039;&#039;&#039;&lt;br /&gt;
Folgende X10-Security-Sensoren werden erfolgreich eingesetzt:&lt;br /&gt;
&lt;br /&gt;
* Türsensoren:&lt;br /&gt;
** X10 Türsensor Powerhouse DS10A ([http://www.domotica.famschenk.eu/DS10A_op_433Mhz.html Umbau auf 433 Mhz])&lt;br /&gt;
** Marmitek Türsensor DS90&lt;br /&gt;
* Bewegungssensoren: &lt;br /&gt;
** X10 Bewegungssensor Powerhouse MS10A ([http://www.domotica.famschenk.eu/MS10A-433.html Umbau auf 433 Mhz])[[File:Ms10a.png|70px|right|thumb|MS10A]]&amp;lt;div class=&amp;quot;tright&amp;quot; style=&amp;quot;clear:none&amp;quot;&amp;gt;[[File:Ms90.png|82px|mini|ohne|MS90]]&amp;lt;/div&amp;gt;&lt;br /&gt;
** Marmitek Bewegungssensor MS10E/BNL (kompatibel mit X10 MS10)&lt;br /&gt;
** Marmitek Bewegungssensor MS90 &lt;br /&gt;
* Rauchmelder:&lt;br /&gt;
** Marmitek Rauchmelder SD90&lt;br /&gt;
&lt;br /&gt;
Die oben genannten Sensoren können auch parallel zum RFXtrx433 mit der Marmitek-Alarmanlage SC9000 eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* Fernbedienungen:&lt;br /&gt;
** Marmitek KR21E [[File:Kr21e.png|60px|right|thumb|KR21E]]&amp;lt;div class=&amp;quot;tright&amp;quot; style=&amp;quot;clear:none&amp;quot;&amp;gt;[[File:Sh624.png|75px|mini|ohne|SH624]]&amp;lt;/div&amp;gt;&lt;br /&gt;
** Marmitek SH624 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
X10-Security-Sensoren senden etwa jede Stunde ein Keepalive-Paket, welches auch Informationen über den Batterieladestand enthält.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bewegungsmelder&lt;br /&gt;
** Oregon MSR939 (benötigt den RFXtrx433e), theoretisch 32 Adressen möglich, 5 Stück erfolgreich eingebunden (mehr Sensoren hatte ich nicht zur Hand)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Modul: TRX_LIGHT.pm ==&lt;br /&gt;
Empfängt die Protokolle X10, ARC, ELRO AB400D, Waveman, Chacon EMW200, IMPULS, RisingSun, Philips SBC, AC, HomeEasy EU sowie ANSLUT lighting devices (switches and remote control). &lt;br /&gt;
&lt;br /&gt;
ARC ist ein a Protokoll, welches von Geräten HomeEasy, KlikAanKlikUit, ByeByeStandBy, Intertechno, ELRO, AB600, Duewi, DomiaLite und COCO genutzt wird. Typisch ist, dass diese Geräte einen Drehschalter haben, um die Protkolladresse einzustellen.&lt;br /&gt;
&lt;br /&gt;
Das ARC-Protokoll kennt keinen Dim-Befehl. Daher hat die Firmware vom RFXtrx433 und auch das FHEM-Modul TRX_LIGHT keinen solchen Befehl. Die verkauften Dimmer mit ARC-Protokoll starten gemäß meiner Information das Hoch-Dimmen nach Empfang zweier ON-Kommandos. Sobald dann das nächste ON oder OFF Kommando empfangen wird, wird das Dimmen beendet.&lt;br /&gt;
Das ganze ist also zeitabhängig und eigentlich nicht für die Hausautomatisierung gedacht, sondern für den Menschen, der sieht, ob der Dim-Level ok ist. Automatisiert bekommt man keine exakte prozentuale Dimmung hin, da man Dimmen nur über Timing erreichen kann.&lt;br /&gt;
Da FHEM nicht sehen kann wie weit gedimmt wurde, ist das allerdings nicht wirklich praktikabel und auch vom Gerät abhängig.&lt;br /&gt;
Unterschiedliche Geräte auch unterschiedliches Zeitverhalten.&lt;br /&gt;
&lt;br /&gt;
AC ist ein Protokoll, welches verschiedene Hersteller nutzen, die die Adresse über einen LEARN-Button lernen: KlikAanKlikUit, NEXA, CHACON, HomeEasy UK.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039;Es sollte beachtet werden, dass Tür- und Bewegungssensoren des AC-Protokolls (HomeEasy alt, Chacon, KlikAanKlikUit, NEXA...) teilweise für 3-5 Sekunden etwa 50 Funkpakete generieren, was zu Kollisionen mit anderen Paketen führen kann. Siehe [http://www.domoticaforum.eu/viewtopic.php?f=7&amp;amp;amp;t=7276 Hinweis zur Nutzung von Bewegungssensoren]. Ich rate daher vom Einsatz von Bewegungssensoren mit dem AC-Protokoll ab.&lt;br /&gt;
&lt;br /&gt;
Der Autor des Moduls setzt derzeit folgende Geräte ein:&lt;br /&gt;
&lt;br /&gt;
* Eagle EyeMS14a Bewegungssensor ([http://www.domotica.famschenk.eu/MS14A_OP_433.92.html Umbau auf 433 Mhz])&lt;br /&gt;
* Elro AB600 Funksender und Steckdosen&lt;br /&gt;
&lt;br /&gt;
Nutzer haben die Funktion folgender Geräte gemeldet:&lt;br /&gt;
&lt;br /&gt;
* KAKU AWST-6000 (Bewegungsmelder, sendet on/off)&lt;br /&gt;
* KAKU AMST-606 (Tür-/Fenster-Kontakt, sendet all_level/off)&lt;br /&gt;
* KAKU AWMT-230 (Unterputzsender, sendet on/off)&lt;br /&gt;
* KAKU APA3-1500R (Schalter &amp;amp;amp; Handsender, nur on/off/all_off)&lt;br /&gt;
* KAKU CDB-6500AC (Türklingel, sendet nur chime)&lt;br /&gt;
&lt;br /&gt;
== PT2262 empfangen und senden mit TRX_LIGHT.pm ==&lt;br /&gt;
&#039;&#039;&#039;WARNUNG:&#039;&#039;&#039;PT2262-Codes sollten nur verwendet werden, wenn unbedingt erforderlich. Normalerweise reicht die Nutzung der von RFXCOM vordefinierten Dekodierungen wie das ARC-Protokoll aus. Bei manchen Geräten mit dem Chip PT2262 kann dies evtl. nicht ausreichen. Sinnvollerweise sollte man prüfen, ob das Gerät wirklich einen Funk-Encoder-IC PT2262 oder SC2262 enthält. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Es können nur PT2262-Codes empfangen werden, wenn das Pulse-Timung 350 usec ist (Siehe Kapitel 8 im RFXtrx User Guide). Gemäß Seite 6 im Dokument http://www.escol.com.my/Datasheets_specs/pt2262_1.pdf‎ sollte für den Oszillator normalerweise ein 3,3 Mega-Ohm-Widerstand eingebaut sein.&lt;br /&gt;
&lt;br /&gt;
=== PT2262-Format empfangen ===&lt;br /&gt;
Das Funk-Encoder-IC PT2262 der Firma PTC Taiwan (siehe [http://pdf.dzsc.com/88889/21967.pdf http://pdf.dzsc.com/88889/21967.pdf]) wird häufig in Fernbedienungen von Funksteckdosen und auch anderen Funkgeräten im 433-Mhz-Bereich verwendet. Es gibt viele PIN kompatible ICs wie z.B. der SC2262.&lt;br /&gt;
&lt;br /&gt;
Es werden hierbei 12 Zeichen im Tristate-Format (0, 1, 2 bzw. f) übertragen. Der erste Teil der Zeichen stellt die Adresse und die darauffolgenden Zeichen die Datenbits (Zeichen 0 oder 1) dar.&lt;br /&gt;
Die verwendeten Fernbedienungen haben häufig Dip-Schalter mit drei Zuständen (also 0,1,2), mit denen sich die Adressen einstellen lassen.&lt;br /&gt;
&lt;br /&gt;
Das Protokoll ist vom Aufbau ähnlich zum ARC-Protokoll. &lt;br /&gt;
&lt;br /&gt;
Dabei lassen sich die ersten 6-12 Zeichen als Adressen (A0 bis A11) und die letzten 0-6 Zeichen (D5-D0) als Datenbits nutzen. Es sind damit insgesamt folgende Kombinationen der Bits möglich:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11&lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 D0 &lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 D1 D0&lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 A7 A8 D2 D1 D0&lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 A7 D3 D2 D1 D0 &lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 D4 D3 D2 D1 D0 &lt;br /&gt;
A0 A1 A2 A3 A4 A5 D5 D4 D3 D2 D1 D0&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Damit lassen sich also maximal 6-Bit-Daten übertragen. Dies reicht für einfache Schaltaufgaben, aber nicht für Anwendungen wie beispielsweise Thermometer.&lt;br /&gt;
&lt;br /&gt;
RFXtrx433 läßt sich über RFXmngr so konfigurieren, dass die 12-Zeichen-Datagramme des PT2262-Formats als 24-Bit-Nutzdaten bzw. 3 Bytes empfangen werden können. Dazu kann man in RFXmngr das Protokoll Lighting4 einschalten.&lt;br /&gt;
Hinweise zur Nutzung sind in [http://www.rfxcom.com/WebRoot/StoreNL2/Shops/78165469/MediaGallery/Downloads/RFXtrx_User_Guide.pdf RFXtrx User Guide] (Kapitel &amp;quot;15. Transmit undecoded ARC commands&amp;quot;) zu finden.&lt;br /&gt;
&lt;br /&gt;
Das FHEM-Modul TRX_LIGHT erlaubt die Verarbeitung des PT2262-Formates.&lt;br /&gt;
&lt;br /&gt;
Sobald Lighting4 eingeschaltet wird, werden die einzelnen Bits dem Gerät TRX_PT2262 zugeordnet. Sofern dieses noch nicht vorhanden ist, wird diesen per Autocreate definiert und ein entsprechendes Filelog angelegt.&lt;br /&gt;
&lt;br /&gt;
Wenn beispielsweise ein Nutzer einen Taster einer ELRO AB600 Fernbedienung drückt, werden je nach Codierung der Adresse folgende Codes im Filelog generiert:&lt;br /&gt;
&lt;br /&gt;
* Drücken der Taste &amp;quot;on&amp;quot;:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;2012-12-30_21:40:42 TRX_PT2262 111101110111&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* Drücken von &amp;quot;off&amp;quot;:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;2012-12-30_21:40:47 TRX_PT2262 111101110110&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Auf diese Weise kann ein Nutzer sehen, welche PT2262-Codes von RFXtrx433 empfangen werden.&lt;br /&gt;
&lt;br /&gt;
Der Nutzer muss danach selbst entscheiden, welche Zeichen Adressen und welche Daten darstellen und was die Daten bedeuten. Im oben genannten Beispiel ist dies relativ einfach. Man sieht, dass sich nur das letzte Bit ändern und die Zustände 0 und 1 annimmt. Es ist daher anzunehmen, dass die ersten 11 Zeichen die Adresse repräsentieren.&lt;br /&gt;
&lt;br /&gt;
TRX_LIGHT bietet die Möglichkeit den Adressprefix, die sogenannte deviceid selbst in einem define-Statement festzulegen.&lt;br /&gt;
Die Konvention ist dabei, dass die einzelnen Zeichen der Base4-Codierung angegeben werden müssen:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define &amp;amp;lt;name&amp;amp;gt; TRX_LIGHT PT2262 &amp;amp;lt;deviceid&amp;amp;gt; &amp;amp;lt;devicelog&amp;amp;gt; [&amp;amp;lt;commandcodes&amp;amp;gt;]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
In commandcodes gibt man optional an wie die Ziffern Strings wie beispielsweise &amp;quot;on&amp;quot; oder &amp;quot;off&amp;quot; zugeordnet werden sollen. Dabei können über Komma getrennt wie die Ziffern den einzelnen Strings zugeordnet werden sollen. Jede einzelne Zuordnung wird über&amp;amp;#160;: angegeben. Zusätzlich sollte ein entsprechendes FileLog definiert werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 define TRX_MYREMOTE1 TRX_LIGHT PT2262 11110111011 light 0:off,1:on&lt;br /&gt;
&lt;br /&gt;
 define FileLog_TRX_MYREMOTE1 FileLog /var/log/fhem/TRX_MYREMOTE1-%Y.log TRX_MYREMOTE1&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird die Ziffer 0 &amp;quot;off&amp;quot; und die Ziffer 1 &amp;quot;on&amp;quot; zugeordnet.&lt;br /&gt;
&lt;br /&gt;
Damit werden nach Drücken der Tasten on und off folgende Einträge im Filelog wie folgt generiert:&lt;br /&gt;
&lt;br /&gt;
   ==&amp;amp;gt; TRX_MYREMOTE1-2012.log &amp;amp;lt;==&lt;br /&gt;
   2012-12-30_21:54:56 TRX_MYREMOTE1 light: on&lt;br /&gt;
   2012-12-30_21:54:56 TRX_MYREMOTE1 on&lt;br /&gt;
&lt;br /&gt;
   ==&amp;amp;gt; TRX_MYREMOTE1-2012.log &amp;amp;lt;==&lt;br /&gt;
   2012-12-30_21:54:59 TRX_MYREMOTE1 light: off&lt;br /&gt;
   2012-12-30_21:54:59 TRX_MYREMOTE1 off&lt;br /&gt;
&lt;br /&gt;
=== PT2262-Format senden ===&lt;br /&gt;
Mit dem Funk-Decoder-IC PT2272 lassen sich Signale von PT2262-Sendern empfangen.&lt;br /&gt;
RFXtrx433 ist in der Lage Funksignale im PT2262-Format zu senden, die dann mit Geräten empfangen werden können, die über den Funk-Decoder-IC PT2272 verfügen. Dazu ist es nicht erforderlich in RFXmngr das Protokoll Lighting4 einzuschalten.&lt;br /&gt;
&lt;br /&gt;
PT2262-Codes können über ein set-Kommando des vorher zu definierenden PT2262-Devices gesendet werden. Die Definition wurde auch schon bei &amp;quot;PT2262-Format empfangen&amp;quot; beschrieben.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define &amp;amp;lt;name&amp;amp;gt; TRX_LIGHT PT2262 &amp;amp;lt;deviceid&amp;amp;gt; &amp;amp;lt;devicelog&amp;amp;gt; [&amp;amp;lt;commandcodes&amp;amp;gt;]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define TRX_MYREMOTE1 TRX_LIGHT PT2262 11110111011 light 0:off,1:on&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Sobald das Device definiert wurde, kann der Code mittels set gesendet werden. Dabei kann man entweder der Base4-Code direkt angegeben werden oder der String der in &amp;amp;lt;commandcodes&amp;amp;gt; definiert wurde.&lt;br /&gt;
&lt;br /&gt;
Beispiele (senden von 1):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;set TRX_MYREMOTE1 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;set TRX_MYREMOTE1 on&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;set TRX_MYREMOTE1 off&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Damit ein PT2262 Code gesendet werden kann, muss der Base4-Code bestehend aus &amp;amp;lt;deviceid&amp;amp;gt; und den Daten genau 12 Base4-Zeichen haben.&lt;br /&gt;
&lt;br /&gt;
Die mittels &amp;amp;lt;commandcodes&amp;amp;gt; definierten Strings werden in der Auswahlliste von set in der Weboberfläche von FHEM berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
=== PT2262-Format am Beispiel der Brennenstuhl (RCS 2044 N) Steckdosen ===&lt;br /&gt;
&lt;br /&gt;
Etwas verwirrend ist die Base-4-Codierung in FHEM und die Binärcodierung im RFXtrx, und weil mich das ein paar Minuten beschäftigt hat, beschreibe ich mal die Vorgehensweise exemplarisch mit dem o.a. Funk-Schaltdosensystem.&lt;br /&gt;
&lt;br /&gt;
==== Vorbereitung (Hardware einstellen) ====&lt;br /&gt;
&lt;br /&gt;
Zuallererst muss man sicherstellen, dass der &amp;quot;System-&amp;quot;Code aller Geräte, sprich des Senders und jedes Empfängers gleich ist, das sind die DIP-Switches (aka &amp;quot;Mäuseklavier&amp;quot;)  1-5. &amp;quot;ON&amp;quot; ist eine 0, &amp;quot;OFF&amp;quot; eine 1. Dieser Konfiguration werden wir gleich noch begegnen. Stellen Sie also mal gleich alle Geräte auf eine andere Konfiguration als die ausgelieferte (sonst schalten Sie möglicherweise die Steckdosen des netten Nachbars), aber alle Geräte auf die gleiche Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer will, teste nun alle Steckdosen, ob sie mit der Fernbedienung schaltbar sind, ob also die Switches alle passen.&lt;br /&gt;
&lt;br /&gt;
==== Konfiguration für FHEM ====&lt;br /&gt;
&lt;br /&gt;
Nun zu FHEM: Erst einmal probiert man ja verschiedene Protokolle im &#039;&#039;RfxMgr&#039;&#039;. Also den Empfänger an den PC anschließen und im &#039;&#039;RfxMgr&#039;&#039; die Verbindung aufbauen. Im &#039;&#039;User Guide&#039;&#039; steht, dass das nötige Protokoll &#039;&#039;Lighting4&#039;&#039; ist, also ankreuzen und &#039;&#039;Set Mode&#039;&#039; anklicken. Wenn man nun eine Taste der Fernbedienung drückt, kommt so was wie&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Packettype    = Lighting4&lt;br /&gt;
 subtype       = PT2262&lt;br /&gt;
 Sequence nbr  = 6&lt;br /&gt;
 Code          = 455451 decimal:4543569&lt;br /&gt;
 S1- S24  = 0100 0101 0101 0100 0101 0001 &lt;br /&gt;
 Pulse         = 325 usec&lt;br /&gt;
 Signal level  = 7  -64dBm&lt;br /&gt;
 ------------------------------------------------&lt;br /&gt;
 ------------------------------------------------&lt;br /&gt;
 Packettype    = Lighting4&lt;br /&gt;
 subtype       = PT2262&lt;br /&gt;
 Sequence nbr  = 7&lt;br /&gt;
 Code          = 45555F decimal:4543839&lt;br /&gt;
 S1- S24  = 0100 0101 0101 0101 0101 1111 &lt;br /&gt;
 Pulse         = 324 usec&lt;br /&gt;
 Signal level  = 7  -64dBm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kommen meist 2 Meldungen, zuerst das Kommando. Die zweite Meldung kann uns egal sein, sie kommt nicht immer und hat denselben Wert, egal ob eine Steckdose geschaltet wird oder nicht (also kein Fehlerstatus), und egal ob sie ein- oder ausgeschaltet ist.&lt;br /&gt;
&lt;br /&gt;
===== Decodierung des Systemcodes =====&lt;br /&gt;
&lt;br /&gt;
Nun steht überall hier im Artikel &amp;quot;12 Base4-Zeichen&amp;quot;. Wir haben 24 Binärzeichen. Das läßt sich übersetzen, indem man immer 2 Binärzeichen zu einem Base4-Zeichen zusammenfasst:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;0100 0101 0101 0100 0101 0001&lt;br /&gt;
 1 0  1 1  1 1  1 0  1 1  0 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
nach dem Prinzip:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;00 = 0, 01 = 1, 10 = 2, 11 = 3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und wenn man sich die DIP-Switches anschaut, und den Wert oben (hier &amp;quot;101111101101&amp;quot; durchgeht, fällt einem auf: die ersten 5 Zahlen sind genau die Stellungen der DIP-Switches:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;10111 = OFF ON OFF OFF OFF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und tatsächlich sind diese 5 Zahlen bei allen Tasten gleich: die Decodierung der ersten 5 Zahlen ist geschafft.&lt;br /&gt;
&lt;br /&gt;
===== Decodierung der Steckdosen-Zuordnung =====&lt;br /&gt;
&lt;br /&gt;
Dann geht man die verschiedenen Steckdosen-IDs durch, jeweils der &amp;quot;EIN&amp;quot;-Schalter, ergibt (suggestiv formatiert):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;EIN=10111 01111 01, AUS=10111 01111 11 (Steckdose 1)&lt;br /&gt;
EIN=10111 10111 01, AUS=10111 10111 11 (Steckdose 2)&lt;br /&gt;
EIN=10111 11011 01, AUS=10111 11011 11 (Steckdose 3)&lt;br /&gt;
EIN=10111 11101 01, AUS=10111 11101 11 (Steckdose 4)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also sind die nächsten 5 Zahlen die Zuordnung der Steckdosen. Jede Stelle beschreibt den Zustand des passenden DIP-Switches &amp;quot;A&amp;quot; bis &amp;quot;E&amp;quot;, wie üblich &amp;quot;0&amp;quot; ist &amp;quot;ON&amp;quot;, &amp;quot;1&amp;quot; ist &amp;quot;OFF&amp;quot;. Ob die Steckdosen mit mehr als einem auf OFF gelegten &amp;quot;A&amp;quot; bis &amp;quot;E&amp;quot;-Switch funktionieren, habe ich nicht getestet, aber es erscheint logisch, man könnte dann bis zu 32 Steckdosen auf den gleichen Systemcode legen, und ein Nachbar mit Fernbedienung kann nichts Böses anrichten! FHEM kann es egal sein, man kann ja verschiedene Systemcodes angeben, das geht bei der Fernbedienung nicht. Die ausserdem auch nur einen der &amp;quot;A&amp;quot; bis &amp;quot;D&amp;quot;-Switches adressiert.&lt;br /&gt;
&lt;br /&gt;
===== Ein/Aus-Kommando =====&lt;br /&gt;
&lt;br /&gt;
Bleiben noch 2 Zahlen. Wenn man auf den &amp;quot;AN&amp;quot;-Taster drückt, ist der Wert &amp;quot;01&amp;quot;, bei &amp;quot;AUS&amp;quot; &amp;quot;11&amp;quot;. Da hier wieder alles invertiert ist, steht zu vermuten, dass davon nur die erste Zahl den gewünschten Schaltzustand beschreibt, &amp;quot;01&amp;quot; -&amp;gt; &amp;quot;0&amp;quot; -&amp;gt; &amp;quot;EIN&amp;quot;. &amp;quot;11&amp;quot; -&amp;gt; &amp;quot;1&amp;quot; -&amp;gt; &amp;quot;AUS&amp;quot;. Was die letzte Stelle ist: keine Ahnung.&lt;br /&gt;
&lt;br /&gt;
Geschafft: jetzt ist die Fernbedienung in FHEM folgendermassen zu konfigurieren:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;defmod Steckdose_brennenstuhl_aussen TRX_LIGHT PT2262 1011101111 light 01:on,10:off&lt;br /&gt;
defmod Steckdose_brennenstuhl_1 TRX_LIGHT PT2262      1011110111 light 01:on,10:off&lt;br /&gt;
defmod Steckdose_brennenstuhl_2 TRX_LIGHT PT2262      1011111011 light 01:on,10:off&lt;br /&gt;
defmod Steckdose_brennenstuhl_3 TRX_LIGHT PT2262      1011111101 light 01:on,10:off&lt;br /&gt;
attr Steckdose_brennenstuhl_.* Funksteckdosen,RFXcom&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Natürlich sind die ersten 5 Zahlen bei Ihrem System anders als meine, insbesondere wenn Sie direkt neben mir wohnen, bitte ;))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis&#039;&#039;&#039;: Man kann natürlich auch bei jeder Steckdose die ersten 5 Switches anders einstellen, also alle 10 Stellen, aber dann kann man die Fernbedienung nicht mehr verwenden, um mehrere zu schalten.&lt;br /&gt;
&lt;br /&gt;
Adventsbeleuchtung gefällig?&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define di_adventsbeleuchtung   DOIF ([{sunset(-1800)}-24:00])  (set Steckdose_brennenstuhl_aussen on) DOELSE (set Steckdose_brennenstuhl_aussen off)&lt;br /&gt;
define di_adventsbeleuchtung_2 DOIF ([05:45-{sunrise(+1800)}]) (set Steckdose_brennenstuhl_aussen on) DOELSE (set Steckdose_brennenstuhl_aussen off)&lt;br /&gt;
define di_adventsbeleuchtung_3 DOIF ([{sunset(-1800)}-01:00])  (set Steckdose_brennenstuhl_1 on) DOELSE (set Steckdose_brennenstuhl_1 off)&lt;br /&gt;
define di_adventsbeleuchtung_4 DOIF ([05:35-{sunrise(+1800)}]) (set Steckdose_brennenstuhl_1 on) DOELSE (set Steckdose_brennenstuhl_1 off)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fragen und Antworten (FAQ) ==&lt;br /&gt;
&lt;br /&gt;
=== Warum wird mein RFXtrx433 nicht erkannt? ===&lt;br /&gt;
&lt;br /&gt;
Das Gerät hat einen FTDI-FT232R-USB-Interface-Chip installiert. Um RFXtrx433 nutzen zu können, muss das Betriebssystem einen entsprechenden Treiber für diesen Chip haben. Dies ist normalerweise bei Linux oder Fritzbox 7390 der Fall. Bei Windows muss ein entsprechender Treiber installiert werden. Siehe auch http://www.rfxcom.com/Documents/RFXtrx%20User%20Guide.pdf .&lt;br /&gt;
&lt;br /&gt;
Bei Fritzbox 7270 und 7170 werden vom Hersteller AVM mit der Firmware keine Treiber für den FTDI-FT232R-USB-Interface-Chip mitgeliefert. &lt;br /&gt;
&lt;br /&gt;
=== Warum werden die Tasten meiner Fernbedienung nicht alle erkannt? ===&lt;br /&gt;
Ist geklärt, dass die Fernbedienung von der Firmware supportet wird? Gerade beim ARC-Protokoll ist es häufig so, dass die Hersteller unterschiedliche Codierungen verwenden. &lt;br /&gt;
&lt;br /&gt;
Es wurde berichtet, dass die Tasten folgende Fernbedienungen von der Firnware des RFXtrx433 nicht alle richtig erkannt werden:&lt;br /&gt;
* ELRO AB440RA&lt;br /&gt;
Bei folgende Fernbedienungen wurden berichtet, dass diese richtig erkannt werden:&lt;br /&gt;
* ELRO AB600RA&lt;br /&gt;
&lt;br /&gt;
Bitte weitere Fernbedienungen melden!&lt;br /&gt;
[[Kategorie:Interfaces]]&lt;br /&gt;
[[Kategorie:Temperatursensoren]]&lt;br /&gt;
[[Kategorie:Bewegungs- und Anwesenheitsmelder]]&lt;br /&gt;
[[Kategorie:Rauchmelder]]&lt;br /&gt;
[[Kategorie:Luftdrucksensor]]&lt;br /&gt;
[[Kategorie:Regensensor]]&lt;br /&gt;
[[Kategorie:Wetterstationen]]&lt;br /&gt;
[[Kategorie:Dimmer]]&lt;br /&gt;
[[Kategorie:Feuchtesensoren]]&lt;br /&gt;
[[Kategorie:Other_Components]]&lt;br /&gt;
[[Kategorie:Waagen]]&lt;br /&gt;
[[Kategorie:Lichtsensoren]]&lt;br /&gt;
[[Kategorie:Energieverbrauchsmessung]]&lt;br /&gt;
[[Kategorie:Energieerzeugungsmessung]]&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=RFXtrx&amp;diff=17641</id>
		<title>RFXtrx</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=RFXtrx&amp;diff=17641"/>
		<updated>2016-12-01T17:26:54Z</updated>

		<summary type="html">&lt;p&gt;C2j2: Beispiel-Anleitung für die Konfiguration von Brennenstuhl Funksteckdosen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Fhem unterstützt viele durch einen &#039;&#039;&#039;RFXtrx&#039;&#039;&#039;433 Transceiver erreichbare Geräte durch eigene Module.&lt;br /&gt;
&lt;br /&gt;
== Übersicht ==&lt;br /&gt;
[[File:Rfxtrx433.png|500px|right]]&lt;br /&gt;
&lt;br /&gt;
RFXtrx433 ist ein Transceiver (Funkempfänger und Funksender) mit USB-Anschluss für den Frenzbereich 433,92 MHz. Die Stromversorgung erfolgt über USB.  Das Gerät hat einen FTDI-FT232R-USB-Interface-Chip installiert. Um RFXtrx433 nutzen zu können, muss das Betriebssystem einen entsprechenden Treiber für diesen Chip haben. Genutzt wird RFXtrx433 von Anwendern mit FHEM unter Linux, Fritzbox 7390 oder Windows.&lt;br /&gt;
&lt;br /&gt;
Mit der mitgelieferten Firmware können viele Funksensoren in diesem Frequenzbereich empfangen werden und es ist möglich bestimmte Protokolle auch zu senden. Die unterstützten Protokolle sind von der installierten Firmware abhängig, die über das Windows-Programm [http://www.rfxcom.com/Downloads RFXflash] aktualisiert werden kann. Die neueste Firmware ist unter [http://www.rfxcom.com/Downloads http://www.rfxcom.com/Downloads] zu finden.&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen zu den von diesem Transceiver verfügbaren Protokolle beim Hersteller unter [http://www.rfxcom.com www.rfxcom.com]. Da der Hersteller die Anzahl der Geräte ständig aktualisiert und die FHEM-Treiber in der Freizeit des Autors geschrieben werden, sind in den FHEM-Treibern nur eine Untermenge implementiert. Sollte ein Gerät/Protokoll fehlen, das die Firma RFXCOM unterstützt, können Sie im [http://forum.fhem.de/ FHEM-Forum] in der Untergruppe RFXTRX nachfragen, ob dieses implementiert werden kann.&lt;br /&gt;
&lt;br /&gt;
TRXtrx433 wird derzeit von FHEM mit den Modulen TRX, TRX_LIGHT, TRX-SECURITY und TRX_WEATHER für eine Reihe von Protokollen unterstützt.&lt;br /&gt;
&lt;br /&gt;
Nachfolgend werden nur Geräte aufgezeigt, die bei der Erstellung dieses WIKI-Eintrages eingepflegt werden.&lt;br /&gt;
&lt;br /&gt;
== FHEM-Modul: TRX_WEATHER ==&lt;br /&gt;
Dieses Modul unterstützt Wettersensoren, insbesondere Sensoren des Herstellers Oregon-Scientific. Unter [http://www.rfxcom.com/oregon.htm Wetter-Sensoren] finden Sie eine Liste der von der RFXtrx433-Firmware unterstützten Wetter-Sensoren (Oregon-Scientific, Cresta, La Crosse, TFA, UPM, ...). Das FHEM-Modul TRX_WEATHER implementiert derzeit den Empfang folgender Sensorentypen und Sensoren:&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Temperatursensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;THR128&amp;quot;: Oregon-Scientific THR128/138, THC138&lt;br /&gt;
* &amp;quot;THGR132N&amp;quot;: Oregon-Scientific THC238/268,THN132,THWR288,THRN122,THN122,AW129/131&lt;br /&gt;
* &amp;quot;THWR800&amp;quot;: Oregon-Scientific THWR800&lt;br /&gt;
* &amp;quot;RTHN318&amp;quot;: Oregon-Scientific RTHN318&lt;br /&gt;
* &amp;quot;TS15C&amp;quot;: TS15C&lt;br /&gt;
* &amp;quot;VIKING_02811&amp;quot; : Viking 02811&lt;br /&gt;
* &amp;quot;WS2300&amp;quot; : La Crosse WS2300&lt;br /&gt;
* &amp;quot;RUBICSON&amp;quot; : RUBiCSON&lt;br /&gt;
* &amp;quot;TFA_303133&amp;quot; : TFA 30.3133&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Temperatur-/Luftffeuchtigkeitssensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;THGR228N&amp;quot;: Oregon-Scientific THGN122/123, THGN132, THGR122/228/238/268 [[File:Thgr228n.png|92px|right|thumb|THGR228N]]&lt;br /&gt;
* &amp;quot;THGR810&amp;quot;: Oregon-Scientific THGR810&lt;br /&gt;
* &amp;quot;RTGR328&amp;quot;: Oregon-Scientific RTGR328&lt;br /&gt;
* &amp;quot;THGR328&amp;quot;: Oregon-Scientific THGR328&lt;br /&gt;
* &amp;quot;WTGR800_T&amp;quot;: Oregon-Scientific WTGR800&lt;br /&gt;
* &amp;quot;THGR918&amp;quot;: Oregon-Scientific THGR918, THGRN228, THGN500&lt;br /&gt;
* &amp;quot;TFATS34C&amp;quot;: TFA TS34C (Kat. Nr. 30.3150)&lt;br /&gt;
* &amp;quot;WT450H&amp;quot;: UPM WT450H&lt;br /&gt;
* &amp;quot;TX3_T&amp;quot;: LaCrosse TX3, TX4, TX17&lt;br /&gt;
[[File:TX3TH.jpg|92px|right|thumb|TX3TH]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Nicht unterstützt werden von der RFXCOM-Firmware:&#039;&#039;&#039; TFA 30.3166&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Temperatur-/Luftffeuchtigkeits-/Luftdrucksensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;BTHR918&amp;quot;: Oregon-Scientific BTHR918&lt;br /&gt;
* &amp;quot;BTHR918N&amp;quot;: Oregon-Scientific/Huger BTHR918N, BTHR968 [[File:Bthr918n.png|96px|right|thumb|BTHR918N]]&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Regensensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;RGR918&amp;quot;: Oregon-Scientific RGR126/682/918&lt;br /&gt;
* &amp;quot;PCR800&amp;quot;: Oregon-Scientific PCR800&lt;br /&gt;
* &amp;quot;TFA_RAIN&amp;quot;: TFA-Regensensor (Kat. Nr. 30.3148)&lt;br /&gt;
* &amp;quot;RG700&amp;quot;: UPM RG700&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Windsensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;WTGR800_A&amp;quot;: Oregon-Scientific WTGR800&lt;br /&gt;
* &amp;quot;WGR800_A&amp;quot;: Oregon-Scientific WGR800&lt;br /&gt;
* &amp;quot;WGR918&amp;quot;: Oregon-Scientific STR918, WGR918&lt;br /&gt;
* &amp;quot;TFA_WIND&amp;quot;: TFA-Windsensor (Kat. Nr. 30.3149)&lt;br /&gt;
* &amp;quot;WDS500&amp;quot; : UPM WDS500&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;UV-Sensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;UVN128&amp;quot;: Oregon UVN128, UV138&lt;br /&gt;
* &amp;quot;UVN800&amp;quot;: Oregon UVN800&lt;br /&gt;
* &amp;quot;TFA_UV&amp;quot;: TFA_UV-Sensor&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Waagen&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;BWR101&amp;quot;: Oregon Scientific BWR101&lt;br /&gt;
* &amp;quot;GR101&amp;quot;: Oregon Scientific GR101&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Energiesensoren&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;CM160&amp;quot;: OWL CM119 und CM160&lt;br /&gt;
* &amp;quot;CM180&amp;quot;: OWL CM180&lt;br /&gt;
&lt;br /&gt;
Der Autor des Module setzt derzeit folgende Sensoren ein:&lt;br /&gt;
&lt;br /&gt;
* Oregon Scientific: BTHR918, BTHR918N, PCR800, RGR918, THGR228N, THR128, THWR288A, WTGR800, WGR918&lt;br /&gt;
&lt;br /&gt;
Von Nutzern wurde die Funktion folgender weiterer Sensoren gemeldet:&lt;br /&gt;
&lt;br /&gt;
* Oregon Scientific GR101&lt;br /&gt;
* Oregon Scientific RTGR-328 (T/H)&lt;br /&gt;
* Honeywell TF-ATS34C (T/H)&lt;br /&gt;
* TFA Regensender 433 MHz, Kat. Nr. 30.3148, siehe [http://tfa-dostmann.de/index.php?id=57 TFA]&lt;br /&gt;
* TFA Windsender 433 MHz, Kat. Nr. 30.3149, siehe [http://tfa-dostmann.de/index.php?id=57 TFA]&lt;br /&gt;
* TFA T/H-Sender 433 MHz, Kat. Nr. 30.3150, siehe [http://tfa-dostmann.de/index.php?id=57 TFA]&lt;br /&gt;
* OWL CM160&lt;br /&gt;
&lt;br /&gt;
=== FAQ: Wie bringe ich FHEM dazu nicht alle paar Sekunden den Zustand der Sensoren zu loggen? ===&lt;br /&gt;
&lt;br /&gt;
Den ein oder anderen hat es schon genervt, dass die Oregon-Sensoren sehr gesprächig sind und damit das Filelog sehr groß wird.&lt;br /&gt;
&lt;br /&gt;
Abhilfe: Hierzu kann man event-min-interval verwenden, um festzulegen, dass Events nur alle x Minuten generiert werden. event-on-change-reading kann man verwenden, dass Änderungen trotzdem sofort bemerkt werden.&lt;br /&gt;
&lt;br /&gt;
Nachfolgend wird ein Oregon-Sensor BTHR918 so konfiguriert, dass er nur alle 10 Minuten loggt, aber beim State die Änderungen sofort geloggt werden.&lt;br /&gt;
&lt;br /&gt;
 define Alte_Garage TRX_WEATHER BTHR918&lt;br /&gt;
 attr Alte_Garage event-min-interval state:600&lt;br /&gt;
 attr Alte_Garage event-on-change-reading state&lt;br /&gt;
 attr Alte_Garage event-on-update-reading .*&lt;br /&gt;
&lt;br /&gt;
Damit man nicht alles loggt, kann man das Logging auf die Zeilen beschränken, die mit T: beginnen:&lt;br /&gt;
&lt;br /&gt;
 define FileLog_Alte_Garage FileLog /var/log/fhem/Alte_Garage-%Y.log Alte_Garage:T\x3a.*&lt;br /&gt;
 attr FileLog_Alte_Garage logtype temp4press8:Temp/Press,temp4hum6dew10:Temp/Hum,text&lt;br /&gt;
&lt;br /&gt;
Damit hat man dann folgendes im Log:&lt;br /&gt;
&lt;br /&gt;
 2013-08-27_12:21:29 Alte_Garage T: 19.9 H: 69 P: 1005 BAT: low&lt;br /&gt;
 2013-08-27_12:31:37 Alte_Garage T: 19.9 H: 69 P: 1005 BAT: low&lt;br /&gt;
 2013-08-27_12:41:45 Alte_Garage T: 19.9 H: 69 P: 1005 BAT: low&lt;br /&gt;
 2013-08-27_12:47:27 Alte_Garage T: 20 H: 68 P: 1005 D: BAT: low&lt;br /&gt;
 2013-08-27_12:57:35 Alte_Garage T: 20 H: 68 P: 1005 D: BAT: low&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wie man sieht, wird normalerweise alle 10 Minuten geloggt. Um 12:47:27 hat sich die Temperatur verändert und damit wurde ausserhalb der Reihe sofort ein Event generiert.&lt;br /&gt;
&lt;br /&gt;
Ja, stimmt, ich muss noch die Batterie des Sensors wechseln (BAT: low) ;-)&lt;br /&gt;
&lt;br /&gt;
== FHEM-Modul: TRX_SECURITY ==&lt;br /&gt;
Empfängt Security-Sensoren der Protokolle X10-Security, KD101 und Visonic. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KD101 kompatible Rauchmelder&#039;&#039;&#039;&lt;br /&gt;
Es wurden folgende KD101-Versionen gemeldet, die mit RXFtrx433 empfangen werden können:&lt;br /&gt;
&lt;br /&gt;
* KD101LD&lt;br /&gt;
* KD101LA&lt;br /&gt;
* Flamingo FA20RF&lt;br /&gt;
* Elro RM150RF&lt;br /&gt;
* Unitec 46779&lt;br /&gt;
&lt;br /&gt;
Die Rauchmelder KD101 (KD101LD, KD101LA, Flamingo FA20RF, Elro RM150RF) haben folgendes Verhalten:&lt;br /&gt;
&lt;br /&gt;
* Wenn der KD101 selbst Rauch feststellt, kann man diesen Alarm über Funk nicht stoppen. Er sendet &amp;quot;alert&amp;quot; über Funk.&lt;br /&gt;
* Wenn man &amp;quot;alarm&amp;quot; über Funk an einen Rauchmelder sendet, dauert der Alarm nur wenige Sekunden. Für einen dauerhaften Alarm muss man also &amp;quot;alert&amp;quot; immer wieder senden.&lt;br /&gt;
* Wenn man die KD101 pairt, bekommen alle gepairten KD101 dieselbe ID.&lt;br /&gt;
* Wenn einer Rauch erkennt, triggert er alle KD101 mit derselben ID (also die gepairten).&lt;br /&gt;
* Nach Drücken der Taste &amp;quot;Test&amp;quot; am Rauchmelder sendet dieser &amp;quot;alert&amp;quot;. Dadurch wird per autocreate der Rauchmelder angelegt.&lt;br /&gt;
* Ein KD101 sendet kein Keepalive-Signal. Man kann also nur testen, ob ein Rauchmelder noch funktioniert, indem man die Test-Taste drückt.&lt;br /&gt;
&lt;br /&gt;
Mittels RFXtrx433 kann man die Befehle &amp;quot;alert&amp;quot; und &amp;quot;pair&amp;quot; an einen Rauchmelder senden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
* set TRX_KD101_a5ca00 alert&lt;br /&gt;
&lt;br /&gt;
Dies sendet den panic-Befehl an den Rauchmelder. Damit hört man ca. 3 Sekunden lang den nervigen Ton des Rauchmelders. Wer diesen länger haben will, muss das set nach ca. 3 Sekunden erneut auslösen.&lt;br /&gt;
Wer man also ein &amp;quot;set DEVICE alert&amp;quot; an einen Rauchmelder schickt, der mit anderen gepairt ist, dann wird der Alarm bei allen gepairten Rauchmeldern ausgelöst.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;X10-Security-Sensoren&#039;&#039;&#039;&lt;br /&gt;
Folgende X10-Security-Sensoren werden erfolgreich eingesetzt:&lt;br /&gt;
&lt;br /&gt;
* Türsensoren:&lt;br /&gt;
** X10 Türsensor Powerhouse DS10A ([http://www.domotica.famschenk.eu/DS10A_op_433Mhz.html Umbau auf 433 Mhz])&lt;br /&gt;
** Marmitek Türsensor DS90&lt;br /&gt;
* Bewegungssensoren: &lt;br /&gt;
** X10 Bewegungssensor Powerhouse MS10A ([http://www.domotica.famschenk.eu/MS10A-433.html Umbau auf 433 Mhz])[[File:Ms10a.png|70px|right|thumb|MS10A]]&amp;lt;div class=&amp;quot;tright&amp;quot; style=&amp;quot;clear:none&amp;quot;&amp;gt;[[File:Ms90.png|82px|mini|ohne|MS90]]&amp;lt;/div&amp;gt;&lt;br /&gt;
** Marmitek Bewegungssensor MS10E/BNL (kompatibel mit X10 MS10)&lt;br /&gt;
** Marmitek Bewegungssensor MS90 &lt;br /&gt;
* Rauchmelder:&lt;br /&gt;
** Marmitek Rauchmelder SD90&lt;br /&gt;
&lt;br /&gt;
Die oben genannten Sensoren können auch parallel zum RFXtrx433 mit der Marmitek-Alarmanlage SC9000 eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
* Fernbedienungen:&lt;br /&gt;
** Marmitek KR21E [[File:Kr21e.png|60px|right|thumb|KR21E]]&amp;lt;div class=&amp;quot;tright&amp;quot; style=&amp;quot;clear:none&amp;quot;&amp;gt;[[File:Sh624.png|75px|mini|ohne|SH624]]&amp;lt;/div&amp;gt;&lt;br /&gt;
** Marmitek SH624 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
X10-Security-Sensoren senden etwa jede Stunde ein Keepalive-Paket, welches auch Informationen über den Batterieladestand enthält.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bewegungsmelder&lt;br /&gt;
** Oregon MSR939 (benötigt den RFXtrx433e), theoretisch 32 Adressen möglich, 5 Stück erfolgreich eingebunden (mehr Sensoren hatte ich nicht zur Hand)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FHEM-Modul: TRX_LIGHT.pm ==&lt;br /&gt;
Empfängt die Protokolle X10, ARC, ELRO AB400D, Waveman, Chacon EMW200, IMPULS, RisingSun, Philips SBC, AC, HomeEasy EU sowie ANSLUT lighting devices (switches and remote control). &lt;br /&gt;
&lt;br /&gt;
ARC ist ein a Protokoll, welches von Geräten HomeEasy, KlikAanKlikUit, ByeByeStandBy, Intertechno, ELRO, AB600, Duewi, DomiaLite und COCO genutzt wird. Typisch ist, dass diese Geräte einen Drehschalter haben, um die Protkolladresse einzustellen.&lt;br /&gt;
&lt;br /&gt;
Das ARC-Protokoll kennt keinen Dim-Befehl. Daher hat die Firmware vom RFXtrx433 und auch das FHEM-Modul TRX_LIGHT keinen solchen Befehl. Die verkauften Dimmer mit ARC-Protokoll starten gemäß meiner Information das Hoch-Dimmen nach Empfang zweier ON-Kommandos. Sobald dann das nächste ON oder OFF Kommando empfangen wird, wird das Dimmen beendet.&lt;br /&gt;
Das ganze ist also zeitabhängig und eigentlich nicht für die Hausautomatisierung gedacht, sondern für den Menschen, der sieht, ob der Dim-Level ok ist. Automatisiert bekommt man keine exakte prozentuale Dimmung hin, da man Dimmen nur über Timing erreichen kann.&lt;br /&gt;
Da FHEM nicht sehen kann wie weit gedimmt wurde, ist das allerdings nicht wirklich praktikabel und auch vom Gerät abhängig.&lt;br /&gt;
Unterschiedliche Geräte auch unterschiedliches Zeitverhalten.&lt;br /&gt;
&lt;br /&gt;
AC ist ein Protokoll, welches verschiedene Hersteller nutzen, die die Adresse über einen LEARN-Button lernen: KlikAanKlikUit, NEXA, CHACON, HomeEasy UK.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039;Es sollte beachtet werden, dass Tür- und Bewegungssensoren des AC-Protokolls (HomeEasy alt, Chacon, KlikAanKlikUit, NEXA...) teilweise für 3-5 Sekunden etwa 50 Funkpakete generieren, was zu Kollisionen mit anderen Paketen führen kann. Siehe [http://www.domoticaforum.eu/viewtopic.php?f=7&amp;amp;amp;t=7276 Hinweis zur Nutzung von Bewegungssensoren]. Ich rate daher vom Einsatz von Bewegungssensoren mit dem AC-Protokoll ab.&lt;br /&gt;
&lt;br /&gt;
Der Autor des Moduls setzt derzeit folgende Geräte ein:&lt;br /&gt;
&lt;br /&gt;
* Eagle EyeMS14a Bewegungssensor ([http://www.domotica.famschenk.eu/MS14A_OP_433.92.html Umbau auf 433 Mhz])&lt;br /&gt;
* Elro AB600 Funksender und Steckdosen&lt;br /&gt;
&lt;br /&gt;
Nutzer haben die Funktion folgender Geräte gemeldet:&lt;br /&gt;
&lt;br /&gt;
* KAKU AWST-6000 (Bewegungsmelder, sendet on/off)&lt;br /&gt;
* KAKU AMST-606 (Tür-/Fenster-Kontakt, sendet all_level/off)&lt;br /&gt;
* KAKU AWMT-230 (Unterputzsender, sendet on/off)&lt;br /&gt;
* KAKU APA3-1500R (Schalter &amp;amp;amp; Handsender, nur on/off/all_off)&lt;br /&gt;
* KAKU CDB-6500AC (Türklingel, sendet nur chime)&lt;br /&gt;
&lt;br /&gt;
== PT2262 empfangen und senden mit TRX_LIGHT.pm ==&lt;br /&gt;
&#039;&#039;&#039;WARNUNG:&#039;&#039;&#039;PT2262-Codes sollten nur verwendet werden, wenn unbedingt erforderlich. Normalerweise reicht die Nutzung der von RFXCOM vordefinierten Dekodierungen wie das ARC-Protokoll aus. Bei manchen Geräten mit dem Chip PT2262 kann dies evtl. nicht ausreichen. Sinnvollerweise sollte man prüfen, ob das Gerät wirklich einen Funk-Encoder-IC PT2262 oder SC2262 enthält. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039; Es können nur PT2262-Codes empfangen werden, wenn das Pulse-Timung 350 usec ist (Siehe Kapitel 8 im RFXtrx User Guide). Gemäß Seite 6 im Dokument http://www.escol.com.my/Datasheets_specs/pt2262_1.pdf‎ sollte für den Oszillator normalerweise ein 3,3 Mega-Ohm-Widerstand eingebaut sein.&lt;br /&gt;
&lt;br /&gt;
=== PT2262-Format empfangen ===&lt;br /&gt;
Das Funk-Encoder-IC PT2262 der Firma PTC Taiwan (siehe [http://pdf.dzsc.com/88889/21967.pdf http://pdf.dzsc.com/88889/21967.pdf]) wird häufig in Fernbedienungen von Funksteckdosen und auch anderen Funkgeräten im 433-Mhz-Bereich verwendet. Es gibt viele PIN kompatible ICs wie z.B. der SC2262.&lt;br /&gt;
&lt;br /&gt;
Es werden hierbei 12 Zeichen im Tristate-Format (0, 1, 2 bzw. f) übertragen. Der erste Teil der Zeichen stellt die Adresse und die darauffolgenden Zeichen die Datenbits (Zeichen 0 oder 1) dar.&lt;br /&gt;
Die verwendeten Fernbedienungen haben häufig Dip-Schalter mit drei Zuständen (also 0,1,2), mit denen sich die Adressen einstellen lassen.&lt;br /&gt;
&lt;br /&gt;
Das Protokoll ist vom Aufbau ähnlich zum ARC-Protokoll. &lt;br /&gt;
&lt;br /&gt;
Dabei lassen sich die ersten 6-12 Zeichen als Adressen (A0 bis A11) und die letzten 0-6 Zeichen (D5-D0) als Datenbits nutzen. Es sind damit insgesamt folgende Kombinationen der Bits möglich:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11&lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 D0 &lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 D1 D0&lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 A7 A8 D2 D1 D0&lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 A7 D3 D2 D1 D0 &lt;br /&gt;
A0 A1 A2 A3 A4 A5 A6 D4 D3 D2 D1 D0 &lt;br /&gt;
A0 A1 A2 A3 A4 A5 D5 D4 D3 D2 D1 D0&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Damit lassen sich also maximal 6-Bit-Daten übertragen. Dies reicht für einfache Schaltaufgaben, aber nicht für Anwendungen wie beispielsweise Thermometer.&lt;br /&gt;
&lt;br /&gt;
RFXtrx433 läßt sich über RFXmngr so konfigurieren, dass die 12-Zeichen-Datagramme des PT2262-Formats als 24-Bit-Nutzdaten bzw. 3 Bytes empfangen werden können. Dazu kann man in RFXmngr das Protokoll Lighting4 einschalten.&lt;br /&gt;
Hinweise zur Nutzung sind in [http://www.rfxcom.com/WebRoot/StoreNL2/Shops/78165469/MediaGallery/Downloads/RFXtrx_User_Guide.pdf RFXtrx User Guide] (Kapitel &amp;quot;15. Transmit undecoded ARC commands&amp;quot;) zu finden.&lt;br /&gt;
&lt;br /&gt;
Das FHEM-Modul TRX_LIGHT erlaubt die Verarbeitung des PT2262-Formates.&lt;br /&gt;
&lt;br /&gt;
Sobald Lighting4 eingeschaltet wird, werden die einzelnen Bits dem Gerät TRX_PT2262 zugeordnet. Sofern dieses noch nicht vorhanden ist, wird diesen per Autocreate definiert und ein entsprechendes Filelog angelegt.&lt;br /&gt;
&lt;br /&gt;
Wenn beispielsweise ein Nutzer einen Taster einer ELRO AB600 Fernbedienung drückt, werden je nach Codierung der Adresse folgende Codes im Filelog generiert:&lt;br /&gt;
&lt;br /&gt;
* Drücken der Taste &amp;quot;on&amp;quot;:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;2012-12-30_21:40:42 TRX_PT2262 111101110111&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* Drücken von &amp;quot;off&amp;quot;:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;2012-12-30_21:40:47 TRX_PT2262 111101110110&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Auf diese Weise kann ein Nutzer sehen, welche PT2262-Codes von RFXtrx433 empfangen werden.&lt;br /&gt;
&lt;br /&gt;
Der Nutzer muss danach selbst entscheiden, welche Zeichen Adressen und welche Daten darstellen und was die Daten bedeuten. Im oben genannten Beispiel ist dies relativ einfach. Man sieht, dass sich nur das letzte Bit ändern und die Zustände 0 und 1 annimmt. Es ist daher anzunehmen, dass die ersten 11 Zeichen die Adresse repräsentieren.&lt;br /&gt;
&lt;br /&gt;
TRX_LIGHT bietet die Möglichkeit den Adressprefix, die sogenannte deviceid selbst in einem define-Statement festzulegen.&lt;br /&gt;
Die Konvention ist dabei, dass die einzelnen Zeichen der Base4-Codierung angegeben werden müssen:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define &amp;amp;lt;name&amp;amp;gt; TRX_LIGHT PT2262 &amp;amp;lt;deviceid&amp;amp;gt; &amp;amp;lt;devicelog&amp;amp;gt; [&amp;amp;lt;commandcodes&amp;amp;gt;]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
In commandcodes gibt man optional an wie die Ziffern Strings wie beispielsweise &amp;quot;on&amp;quot; oder &amp;quot;off&amp;quot; zugeordnet werden sollen. Dabei können über Komma getrennt wie die Ziffern den einzelnen Strings zugeordnet werden sollen. Jede einzelne Zuordnung wird über&amp;amp;#160;: angegeben. Zusätzlich sollte ein entsprechendes FileLog definiert werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 define TRX_MYREMOTE1 TRX_LIGHT PT2262 11110111011 light 0:off,1:on&lt;br /&gt;
&lt;br /&gt;
 define FileLog_TRX_MYREMOTE1 FileLog /var/log/fhem/TRX_MYREMOTE1-%Y.log TRX_MYREMOTE1&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird die Ziffer 0 &amp;quot;off&amp;quot; und die Ziffer 1 &amp;quot;on&amp;quot; zugeordnet.&lt;br /&gt;
&lt;br /&gt;
Damit werden nach Drücken der Tasten on und off folgende Einträge im Filelog wie folgt generiert:&lt;br /&gt;
&lt;br /&gt;
   ==&amp;amp;gt; TRX_MYREMOTE1-2012.log &amp;amp;lt;==&lt;br /&gt;
   2012-12-30_21:54:56 TRX_MYREMOTE1 light: on&lt;br /&gt;
   2012-12-30_21:54:56 TRX_MYREMOTE1 on&lt;br /&gt;
&lt;br /&gt;
   ==&amp;amp;gt; TRX_MYREMOTE1-2012.log &amp;amp;lt;==&lt;br /&gt;
   2012-12-30_21:54:59 TRX_MYREMOTE1 light: off&lt;br /&gt;
   2012-12-30_21:54:59 TRX_MYREMOTE1 off&lt;br /&gt;
&lt;br /&gt;
=== PT2262-Format senden ===&lt;br /&gt;
Mit dem Funk-Decoder-IC PT2272 lassen sich Signale von PT2262-Sendern empfangen.&lt;br /&gt;
RFXtrx433 ist in der Lage Funksignale im PT2262-Format zu senden, die dann mit Geräten empfangen werden können, die über den Funk-Decoder-IC PT2272 verfügen. Dazu ist es nicht erforderlich in RFXmngr das Protokoll Lighting4 einzuschalten.&lt;br /&gt;
&lt;br /&gt;
PT2262-Codes können über ein set-Kommando des vorher zu definierenden PT2262-Devices gesendet werden. Die Definition wurde auch schon bei &amp;quot;PT2262-Format empfangen&amp;quot; beschrieben.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define &amp;amp;lt;name&amp;amp;gt; TRX_LIGHT PT2262 &amp;amp;lt;deviceid&amp;amp;gt; &amp;amp;lt;devicelog&amp;amp;gt; [&amp;amp;lt;commandcodes&amp;amp;gt;]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define TRX_MYREMOTE1 TRX_LIGHT PT2262 11110111011 light 0:off,1:on&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Sobald das Device definiert wurde, kann der Code mittels set gesendet werden. Dabei kann man entweder der Base4-Code direkt angegeben werden oder der String der in &amp;amp;lt;commandcodes&amp;amp;gt; definiert wurde.&lt;br /&gt;
&lt;br /&gt;
Beispiele (senden von 1):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;set TRX_MYREMOTE1 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;set TRX_MYREMOTE1 on&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;set TRX_MYREMOTE1 off&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Damit ein PT2262 Code gesendet werden kann, muss der Base4-Code bestehend aus &amp;amp;lt;deviceid&amp;amp;gt; und den Daten genau 12 Base4-Zeichen haben.&lt;br /&gt;
&lt;br /&gt;
Die mittels &amp;amp;lt;commandcodes&amp;amp;gt; definierten Strings werden in der Auswahlliste von set in der Weboberfläche von FHEM berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
=== PT2262-Format am Beispiel der Brennenstuhl (RCS 2044 N) Steckdosen ===&lt;br /&gt;
&lt;br /&gt;
Etwas verwirrend ist die Base-4-Codierung in FHEM und die Binärcodierung im RFXtrx, und weil mich das ein paar Minuten beschäftigt hat, beschreibe ich mal die Vorgehensweise exemplarisch mit dem o.a. Funk-Schaltdosensystem.&lt;br /&gt;
&lt;br /&gt;
==== Vorbereitung (Hardware einstellen) ====&lt;br /&gt;
&lt;br /&gt;
Zuallererst muss man sicherstellen, dass der &amp;quot;System-&amp;quot;Code aller Geräte, sprich des Senders und jedes Empfängers gleich ist, das sind die DIP-Switches (aka &amp;quot;Mäuseklavier&amp;quot;)  1-5. &amp;quot;ON&amp;quot; ist eine 0, &amp;quot;OFF&amp;quot; eine 1. Dieser Konfiguration werden wir gleich noch begegnen. Stellen Sie also mal gleich alle Geräte auf eine andere Konfiguration als die ausgelieferte (sonst schalten Sie möglicherweise die Steckdosen des netten Nachbars), aber alle Geräte auf die gleiche Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Wer will, teste nun alle Steckdosen, ob sie mit der Fernbedienung schaltbar sind, ob also die Switches alle passen.&lt;br /&gt;
&lt;br /&gt;
==== Konfiguration für FHEM ====&lt;br /&gt;
&lt;br /&gt;
Nun zu FHEM: Erst einmal probiert man ja verschiedene Protokolle im &#039;&#039;RfxMgr&#039;&#039;. Also den Empfänger an den PC anschließen und im &#039;&#039;RfxMgr&#039;&#039; die Verbindung aufbauen. Im &#039;&#039;User Guide&#039;&#039; steht, dass das nötige Protokoll &#039;&#039;Lighting4&#039;&#039; ist, also ankreuzen und &#039;&#039;Set Mode&#039;&#039; anklicken. Wenn man nun eine Taste der Fernbedienung drückt, kommt so was wie&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Packettype    = Lighting4&lt;br /&gt;
 subtype       = PT2262&lt;br /&gt;
 Sequence nbr  = 6&lt;br /&gt;
 Code          = 455451 decimal:4543569&lt;br /&gt;
 S1- S24  = 0100 0101 0101 0100 0101 0001 &lt;br /&gt;
 Pulse         = 325 usec&lt;br /&gt;
 Signal level  = 7  -64dBm&lt;br /&gt;
 ------------------------------------------------&lt;br /&gt;
 ------------------------------------------------&lt;br /&gt;
 Packettype    = Lighting4&lt;br /&gt;
 subtype       = PT2262&lt;br /&gt;
 Sequence nbr  = 7&lt;br /&gt;
 Code          = 45555F decimal:4543839&lt;br /&gt;
 S1- S24  = 0100 0101 0101 0101 0101 1111 &lt;br /&gt;
 Pulse         = 324 usec&lt;br /&gt;
 Signal level  = 7  -64dBm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kommen meist 2 Meldungen, zuerst das Kommando. Die zweite Meldung kann uns egal sein, sie kommt nicht immer und hat denselben Wert, egal ob eine Steckdose geschaltet wird oder nicht (also kein Fehlerstatus), und egal ob sie ein- oder ausgeschaltet ist.&lt;br /&gt;
&lt;br /&gt;
===== Decodierung des Systemcodes =====&lt;br /&gt;
&lt;br /&gt;
Nun steht überall hier im Artikel &amp;quot;12 Base4-Zeichen&amp;quot;. Wir haben 24 Binärzeichen. Das läßt sich übersetzen, indem man immer 2 Binärzeichen zu einem Base4-Zeichen zusammenfasst:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;0100 0101 0101 0100 0101 0001&lt;br /&gt;
 1 0  1 1  1 1  1 0  1 1  0 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
nach dem Prinzip:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;00 = 0, 01 = 1, 10 = 2, 11 = 3&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und wenn man sich die DIP-Switches anschaut, und den Wert oben (hier &amp;quot;101111101101&amp;quot; durchgeht, fällt einem auf: die ersten 5 Zahlen sind genau die Stellungen der DIP-Switches:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;10111 = OFF ON OFF OFF OFF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und tatsächlich sind diese 5 Zahlen bei allen Tasten gleich: die Decodierung der ersten 5 Zahlen ist geschafft.&lt;br /&gt;
&lt;br /&gt;
===== Decodierung der Steckdosen-Zuordnung =====&lt;br /&gt;
&lt;br /&gt;
Dann geht man die verschiedenen Steckdosen-IDs durch, jeweils der &amp;quot;EIN&amp;quot;-Schalter, ergibt (suggestiv formatiert):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;EIN=10111 01111 01, AUS=10111 01111 11 (Steckdose 1)&lt;br /&gt;
EIN=10111 10111 01, AUS=10111 10111 11 (Steckdose 2)&lt;br /&gt;
EIN=10111 11011 01, AUS=10111 11011 11 (Steckdose 3)&lt;br /&gt;
EIN=10111 11101 01, AUS=10111 11101 11 (Steckdose 4)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also sind die nächsten 5 Zahlen die Zuordnung der Steckdosen. Jede Stelle beschreibt den Zustand des passenden DIP-Switches &amp;quot;A&amp;quot; bis &amp;quot;E&amp;quot;, wie üblich &amp;quot;0&amp;quot; ist &amp;quot;ON&amp;quot;, &amp;quot;1&amp;quot; ist &amp;quot;OFF&amp;quot;. Ob die Steckdosen mit mehr als einem auf OFF gelegten &amp;quot;A&amp;quot; bis &amp;quot;E&amp;quot;-Switch funktionieren, habe ich nicht getestet, aber es erscheint logisch, man könnte dann bis zu 32 Steckdosen auf den gleichen Systemcode legen. FHEM kann es egal sein, man kann ja verschiedene Systemcodes angeben, das geht bei der Fernbedienung nicht. Die ausserdem auch nur einen der &amp;quot;A&amp;quot; bis &amp;quot;D&amp;quot;-Switches adressiert.&lt;br /&gt;
&lt;br /&gt;
===== Ein/Aus-Kommando =====&lt;br /&gt;
&lt;br /&gt;
Bleiben noch 2 Zahlen. Wenn man auf den &amp;quot;AN&amp;quot;-Taster drückt, ist der Wert &amp;quot;01&amp;quot;, bei &amp;quot;AUS&amp;quot; &amp;quot;11&amp;quot;. Da hier wieder alles invertiert ist, steht zu vermuten, dass davon nur die erste Zahl den gewünschten Schaltzustand beschreibt, &amp;quot;01&amp;quot; -&amp;gt; &amp;quot;0&amp;quot; -&amp;gt; &amp;quot;EIN&amp;quot;. &amp;quot;11&amp;quot; -&amp;gt; &amp;quot;1&amp;quot; -&amp;gt; &amp;quot;AUS&amp;quot;. Was die letzte Stelle ist: keine Ahnung.&lt;br /&gt;
&lt;br /&gt;
Geschafft: jetzt ist die Fernbedienung in FHEM folgendermassen zu konfigurieren:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;defmod Steckdose_brennenstuhl_aussen TRX_LIGHT PT2262 1011101111 light 01:on,10:off&lt;br /&gt;
defmod Steckdose_brennenstuhl_1 TRX_LIGHT PT2262      1011110111 light 01:on,10:off&lt;br /&gt;
defmod Steckdose_brennenstuhl_2 TRX_LIGHT PT2262      1011111011 light 01:on,10:off&lt;br /&gt;
defmod Steckdose_brennenstuhl_3 TRX_LIGHT PT2262      1011111101 light 01:on,10:off&lt;br /&gt;
attr Steckdose_brennenstuhl_.* Funksteckdosen,RFXcom&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Natürlich sind die ersten 5 Zahlen bei Ihrem System anders als meine, insbesondere wenn Sie direkt neben mir wohnen, bitte ;))&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis&#039;&#039;&#039;: Man kann natürlich auch bei jeder Steckdose die ersten 5 Switches anders einstellen, also alle 10 Stellen, aber dann kann man die Fernbedienung nicht mehr verwenden, um mehrere zu schalten.&lt;br /&gt;
&lt;br /&gt;
Adventsbeleuchtung gefällig?&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;define di_adventsbeleuchtung   DOIF ([{sunset(-1800)}-24:00])  (set Steckdose_brennenstuhl_aussen on) DOELSE (set Steckdose_brennenstuhl_aussen off)&lt;br /&gt;
define di_adventsbeleuchtung_2 DOIF ([05:45-{sunrise(+1800)}]) (set Steckdose_brennenstuhl_aussen on) DOELSE (set Steckdose_brennenstuhl_aussen off)&lt;br /&gt;
define di_adventsbeleuchtung_3 DOIF ([{sunset(-1800)}-01:00])  (set Steckdose_brennenstuhl_1 on) DOELSE (set Steckdose_brennenstuhl_1 off)&lt;br /&gt;
define di_adventsbeleuchtung_4 DOIF ([05:35-{sunrise(+1800)}]) (set Steckdose_brennenstuhl_1 on) DOELSE (set Steckdose_brennenstuhl_1 off)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fragen und Antworten (FAQ) ==&lt;br /&gt;
&lt;br /&gt;
=== Warum wird mein RFXtrx433 nicht erkannt? ===&lt;br /&gt;
&lt;br /&gt;
Das Gerät hat einen FTDI-FT232R-USB-Interface-Chip installiert. Um RFXtrx433 nutzen zu können, muss das Betriebssystem einen entsprechenden Treiber für diesen Chip haben. Dies ist normalerweise bei Linux oder Fritzbox 7390 der Fall. Bei Windows muss ein entsprechender Treiber installiert werden. Siehe auch http://www.rfxcom.com/Documents/RFXtrx%20User%20Guide.pdf .&lt;br /&gt;
&lt;br /&gt;
Bei Fritzbox 7270 und 7170 werden vom Hersteller AVM mit der Firmware keine Treiber für den FTDI-FT232R-USB-Interface-Chip mitgeliefert. &lt;br /&gt;
&lt;br /&gt;
=== Warum werden die Tasten meiner Fernbedienung nicht alle erkannt? ===&lt;br /&gt;
Ist geklärt, dass die Fernbedienung von der Firmware supportet wird? Gerade beim ARC-Protokoll ist es häufig so, dass die Hersteller unterschiedliche Codierungen verwenden. &lt;br /&gt;
&lt;br /&gt;
Es wurde berichtet, dass die Tasten folgende Fernbedienungen von der Firnware des RFXtrx433 nicht alle richtig erkannt werden:&lt;br /&gt;
* ELRO AB440RA&lt;br /&gt;
Bei folgende Fernbedienungen wurden berichtet, dass diese richtig erkannt werden:&lt;br /&gt;
* ELRO AB600RA&lt;br /&gt;
&lt;br /&gt;
Bitte weitere Fernbedienungen melden!&lt;br /&gt;
[[Kategorie:Interfaces]]&lt;br /&gt;
[[Kategorie:Temperatursensoren]]&lt;br /&gt;
[[Kategorie:Bewegungs- und Anwesenheitsmelder]]&lt;br /&gt;
[[Kategorie:Rauchmelder]]&lt;br /&gt;
[[Kategorie:Luftdrucksensor]]&lt;br /&gt;
[[Kategorie:Regensensor]]&lt;br /&gt;
[[Kategorie:Wetterstationen]]&lt;br /&gt;
[[Kategorie:Dimmer]]&lt;br /&gt;
[[Kategorie:Feuchtesensoren]]&lt;br /&gt;
[[Kategorie:Other_Components]]&lt;br /&gt;
[[Kategorie:Waagen]]&lt;br /&gt;
[[Kategorie:Lichtsensoren]]&lt;br /&gt;
[[Kategorie:Energieverbrauchsmessung]]&lt;br /&gt;
[[Kategorie:Energieerzeugungsmessung]]&lt;/div&gt;</summary>
		<author><name>C2j2</name></author>
	</entry>
</feed>