<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Plugins &#8211; SmartHomeNG | smarthome knx homematic mqtt hue 1wire home automation</title>
	<atom:link href="https://www.smarthomeng.de/category/plugins/feed" rel="self" type="application/rss+xml" />
	<link>https://www.smarthomeng.de</link>
	<description>Die Device Integrations-Plattform für Dein Smart Home</description>
	<lastBuildDate>Sat, 02 Nov 2024 12:48:25 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.5</generator>

<image>
	<url>https://www.smarthomeng.de/wp-content/uploads/global/logo_small_152x152-150x150.png</url>
	<title>Plugins &#8211; SmartHomeNG | smarthome knx homematic mqtt hue 1wire home automation</title>
	<link>https://www.smarthomeng.de</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>HomeMatic IP Fernbedienung in SmartHomeNG einbinden</title>
		<link>https://www.smarthomeng.de/homematic-ip-fernbedienung-in-smarthomeng-einbinden</link>
					<comments>https://www.smarthomeng.de/homematic-ip-fernbedienung-in-smarthomeng-einbinden#comments</comments>
		
		<dc:creator><![CDATA[Martin Sinn]]></dc:creator>
		<pubDate>Tue, 01 Dec 2020 11:16:10 +0000</pubDate>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[HomeMatic]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=2639</guid>

					<description><![CDATA[Nachdem ich bereits HomeMatic Fernbedienungen in SmartHomeNG Installationen eingebunden hatte und das quasi ein Selbstgänger war, dachte ich das Einbinden der HmIP-RC8 wäre in ein paar Minuten erledigt: Ein Irrtum! Auf der HomeMatic Seite ware eine Hürde zu umschiffen, die mich etwas Google-Zeit gekostet hat. Das Problem war, dass die Tastendrücke nicht<a class="moretag" href="https://www.smarthomeng.de/homematic-ip-fernbedienung-in-smarthomeng-einbinden"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<p>Nachdem ich bereits HomeMatic Fernbedienungen in SmartHomeNG Installationen eingebunden hatte und das quasi ein Selbstgänger war, dachte ich das Einbinden der <strong>HmIP-RC8</strong> wäre in ein paar Minuten erledigt: <strong>Ein Irrtum!</strong></p>
<div id="attachment_2640" style="width: 310px" class="wp-caption alignleft"><img fetchpriority="high" decoding="async" aria-describedby="caption-attachment-2640" src="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8-142307_f01_gefernbedien_1920x1920-300x300.jpg" alt="" width="300" height="300" class="wp-image-2640 size-medium" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8-142307_f01_gefernbedien_1920x1920-300x300.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8-142307_f01_gefernbedien_1920x1920-150x150.jpg 150w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8-142307_f01_gefernbedien_1920x1920-768x768.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8-142307_f01_gefernbedien_1920x1920-1024x1024.jpg 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8-142307_f01_gefernbedien_1920x1920.jpg 1920w" sizes="(max-width: 300px) 100vw, 300px" /><p id="caption-attachment-2640" class="wp-caption-text">HmIP-RC8</p></div>
<p>Auf der HomeMatic Seite ware eine Hürde zu umschiffen, die mich etwas Google-Zeit gekostet hat. Das Problem war, dass die Tastendrücke nicht in SmartHomeNG ankamen. Das liegt daran, dass sich HomeMatic IP Tast-Devices in der CCU anders verhalten als die klassischen HomeMatic Tast-Devices. Standardmäßig versendet die CCU keine Events von HomeMatic IP Tast-Devices über das RPC API. Man muss der CCU erst beibringen, dass jemand sich für die Events interessiert.</p>
<p>&nbsp;</p>
<p>Das macht man, indem man in der CCU für jede Taste ein Programm anlegt, dass auf das Tasen-Event hört und dann nichts ausführt. Dieses Dummy Programm gibt der CCU nur zu verstehen, dass sich jemand für das Event interessiert und die CCU übertägt dann das Event über das RPC API, so dass das SmartHomeNG Plugin über den Tastendruck informiert wird. Man kann diese Dummy Programme später sogar wieder löschen. Die CCU merkt sich trotzdem, dass sich jemand für die Events des HomeMatic IP Devices interessiert.</p>
<p>Um das Programm für eine Taste anzulegen, in der CCU unter <strong>Einstellungen</strong>/Geräte die Fernbedienung auswählen und den Eintrag durch Klick auf das + Symbol links aussen aufklappen:</p>
<p><a href="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_1.jpg"><img decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_1-1024x336.jpg" alt="" width="750" height="246" class="alignnone wp-image-2662 size-large" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_1-1024x336.jpg 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_1-300x99.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_1-768x252.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_1.jpg 1227w" sizes="(max-width: 750px) 100vw, 750px" /></a></p>
<p>Nun für die gewünschte Taste den Button <strong>Programme</strong> klicken und folgendes Dummy-Programm eingeben (hier im Beispiel für die erste Taste:</p>
<p><a href="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_2.jpg"><img decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_2-1024x318.jpg" alt="" width="750" height="233" class="alignnone wp-image-2664 size-large" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_2-1024x318.jpg 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_2-300x93.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_2-768x239.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_CCU_2.jpg 1264w" sizes="(max-width: 750px) 100vw, 750px" /></a></p>
<p>Nun können die Tasten in SmartHomeNG eingerichtet werden.</p>
<p>Im Webinterface des Homematic Plugins können die zur Einrichtung der Items benötigten Informationen nachgesehen werden. Auf dem Tab homematicIP Geräte ist die Liste der in der CCU bekannten HomeMatic IP Geräte einsehbar. Hier findet sich auch die <strong>HmIP-RC8</strong> Remote. (Falls die Remote erst jetzt in der CCU eingerichtet wurde und in der Liste nicht sichtbar ist, den Button <strong>Aktualisieren</strong> obern rechts klicken)</p>
<p><a href="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_1.jpg"><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_1-1024x480.jpg" alt="" width="750" height="352" class="alignnone wp-image-2670 size-large" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_1-1024x480.jpg 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_1-300x141.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_1-768x360.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_1.jpg 1698w" sizes="(max-width: 750px) 100vw, 750px" /></a></p>
<p>Solange ein HomeMatic Gerät nicht mit einem Item verknüpft ist, wird es grau dargestellt (wie im Bild der Rauchmelder in der Liste über der Fernbedienung).</p>
<p>Um die weiteren Informationen zum Gerät zu erhalten, auf die Zeile des Gerätes klicken. Dann werden die Details unterhalb des Gerätes angezeigt:</p>
<p><a href="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_2.jpg"><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_2-1024x171.jpg" alt="" width="750" height="125" class="alignnone wp-image-2673 size-large" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_2-1024x171.jpg 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_2-300x50.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_2-768x129.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2020/12/HmIP-RC8_shng_2.jpg 1482w" sizes="(max-width: 750px) 100vw, 750px" /></a></p>
<p>In der Zeile ACTIONNODE werden jetzt die verfügbaren Funktionen (PRESS_SHORT und PRESS_LONG) angezeigt, sowie die Kanäle (1 bis 8) für die diese Funktionen verfügbar sind. Zusammen mit der Geräte Adresse hat man jetzt alle Informationen zusammen um die Items einzurichten.</p>
<p>Im folgenden ist exemplarisch die Einrichtung für die ersten zwei Tasten zu sehen. Die Tasten steuern jeweils ein Item an, welches KNX Szenen aktiviert:</p>
<pre><code class="language-yaml">test:
    homematic:
        remote:
            type: foo
            hm_address: 000B1xxxyyyzzz

            taste1:
                type: bool
                hm_address: ..:.
                hm_channel: 1
                hm_function: PRESS_SHORT
                on_update:
                  - wohnung.wohnen.szenen_wb_knx = 0

            taste1_lang:
                type: bool
                hm_address: ..:.
                hm_channel: 1
                hm_function: PRESS_LONG
                on_update:
                  - wohnung.wohnen.szenen_knx = 0

            taste2:
                type: bool
                hm_address: ..:.
                hm_channel: 2
                hm_function: PRESS_SHORT
                on_update:
                  - wohnung.wohnen.szenen_wb_knx = 1

            taste2_lang:
                type: bool
                hm_address: ..:.
                hm_channel: 2
                hm_function: PRESS_LONG
                on_update:
                  - wohnung.wohnen.szenen_knx = 1</code></pre>
<p>&nbsp;</p>
<p>Das Item <strong>test.homematic.remote</strong> hat selber keine Funktion. Hier wird nur für die Sub-Items die <strong>hm_address</strong> des Gerätes festgelegt, damit man den Wert nicht in allen Sub-Items separat eintragen muss.</p>
<p>In den bis zu 16 Sub-Items, die man sinnvoll definieren kann (8 Tasten, jeweils mit kurzem und langem Tastendruck), werden die drei Attribute (hm_address, hm_channel und hm_function) des homematic Plugins angegeben.</p>
<ul>
<li><strong>hm_address</strong> referenziert durch Angabe des Wertes <strong>..:.</strong> auf das Attribut gleichen Namens im Parent Item.</li>
<li><strong>hm_channel</strong> gibt die Tasten-Nummer (<strong>1</strong> bis <strong>8</strong>) an, auf die das Item regieren soll</li>
<li><strong>hm_function</strong> gibt die Art des Tastendrucks (<strong>PRESS_SHORT</strong> oder <strong>PRESS_LONG</strong>) an, auf die das Item reagieren soll</li>
</ul>
<p>Über das Attribut <strong>on_update</strong> wird gesteuert, was SmartHomeNG tun soll, wenn ein Update für dieses Item (also ein Tastendruck) erfolgt. Im Beispiel wird jeweils einem Szenen-Item ein Wert zugewiesen, um die jeweilige Szene zu aktivieren.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/homematic-ip-fernbedienung-in-smarthomeng-einbinden/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>wie ich meinen ersten Shelly über das Plugin mit MQTT eingebunden habe</title>
		<link>https://www.smarthomeng.de/wie-ich-meinen-ersten-shelly-ueber-das-plugin-mit-mqtt-eingebunden-habe</link>
					<comments>https://www.smarthomeng.de/wie-ich-meinen-ersten-shelly-ueber-das-plugin-mit-mqtt-eingebunden-habe#comments</comments>
		
		<dc:creator><![CDATA[Wil Heynen]]></dc:creator>
		<pubDate>Fri, 08 May 2020 19:28:05 +0000</pubDate>
				<category><![CDATA[Beispiel-Implementierungen]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[shelly]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=2521</guid>

					<description><![CDATA[Da ich mit der Implementierung mehrere Stunden gekämpft habe, möchte ich meine Erfahrungen niederschreiben und eine kleine Anleitung erstellen, wie man am einfachsten vorgeht und welche Fehler man dabei machen kann. Zur Vorgeschichte: Meinen ersten Shelly nutze ich dazu, mein Garagentor über SmartVISU zu öffnen; es gibt zwar eine eigene<a class="moretag" href="https://www.smarthomeng.de/wie-ich-meinen-ersten-shelly-ueber-das-plugin-mit-mqtt-eingebunden-habe"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<p>Da ich mit der Implementierung mehrere Stunden gekämpft habe, möchte ich meine Erfahrungen niederschreiben und eine kleine Anleitung erstellen, wie man am einfachsten vorgeht und welche Fehler man dabei machen kann.</p>
<p><strong>Zur Vorgeschichte:</strong><br />
Meinen ersten Shelly nutze ich dazu, mein Garagentor über SmartVISU zu öffnen; es gibt zwar eine eigene App, wie zu allen Smart Home Devices, aber wozu sollte ich für jedes Device eine andere App benutzen. <span id="more-2521"></span></p>
<p>Zunächst musste ich natürlich den Shelly elektrisch anschließen; hierzu gibt es auch schon reichlich Diskussionen in diversen Foren. Ich habe mich für folgende einfache Lösung entschieden und meinen Shelly, wie den Tastschalter oder den Schlüsselschalter angeschlossen.</p>
<p>Da Shelly keine spezielle Taster Funktion kennt, habe ich den Schalter über die App wie ein Treppenlicht konfiguriert; Nach der Betätigung des Schalters wird nach einer Sekunde wieder ausgeschaltet. Das funktioniert dann zunächst schon mal über die App ganz prima.</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/05/Config1-300x124.png" alt="" class="alignnone size-medium wp-image-2523" width="300" height="124" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/05/Config1-300x124.png 300w, https://www.smarthomeng.de/wp-content/uploads/2020/05/Config1-768x316.png 768w, https://www.smarthomeng.de/wp-content/uploads/2020/05/Config1.png 881w" sizes="(max-width: 300px) 100vw, 300px" /> <img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/05/Config2-300x115.png" alt="" class="alignnone size-medium wp-image-2524" width="300" height="115" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/05/Config2-300x115.png 300w, https://www.smarthomeng.de/wp-content/uploads/2020/05/Config2-768x295.png 768w, https://www.smarthomeng.de/wp-content/uploads/2020/05/Config2.png 874w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<p>In SmarthomeNG habe ich dann mein Item wie folgt konfiguriert:</p>
<p style="padding-left: 30px">Tor:<br />
name: Tor<br />
enforce_updates: true<br />
type: bool<br />
visu: &#8218;yes&#8216;<br />
sv_widget: &#8222;{{ basic.stateswitch(&#8218;item&#8216;, &#8218;item&#8216;, &#8218;midi&#8216;, 1, &#8220;, &#8220;, &#8220;, &#8218;blink&#8216;) }}&#8220;</p>
<p>Ohne MQTT habe ich dann einfach eine Logik implementiert, die bei jedem Klick getriggert wird:</p>
<p>/etc/logic.yaml</p>
<p style="padding-left: 30px">Garagentor:<br />
filename: Garage.py<br />
watch_item: Aussen.Garage.Tor</p>
<p>/logics/Garage.py</p>
<p style="padding-left: 30px"># Shelly1<br />
# Garagentor</p>
<p style="padding-left: 30px">import urllib.request</p>
<p style="padding-left: 30px">myurl = &#8222;http://192.168.178.28/relay/0?turn=on&#8220;</p>
<p style="padding-left: 30px">req = urllib.request.urlopen(myurl)<br />
logger.info(&#8222;Garagentor&#8220;)</p>
<p>Damit funktioniert das ganze &#8222;zu Fuß&#8220; und ohne MQTT und Shelly Plugin in SmarthomeNG 1.5</p>
<p><strong>Vorbereitungen in SmarthomeNG 1.7</strong></p>
<p>Zunächst mal muss MQTT aufgesetzt werden; dies habe ich natürlich, dank &#8222;Onkelandy&#8220; über das <strong>setup_all</strong> script gemacht.</p>
<p>Wer nicht das Image benutz muss dann anhand der Komplettanleitung den mosquitto Broker installieren und konfigurieren.</p>
<p>Danach muss MQTT als Modul aktiviert werden; mit 1.7 ist MQTT in den Core gewandert und wird wie folgt aktiviert:</p>
<p>/etc/module.yaml</p>
<p style="padding-left: 30px">mqtt:<br />
module_name: mqtt<br />
broker_monitoring: true</p>
<p>Als einzigen Parameter habe ich das Monitoring eingeschaltet, damit man über das Web GUI die Aktivitäten verfolgen kann.</p>
<p>Dann wir das Shelly Plugin aktiviert:</p>
<p>/etc/plugin.yaml</p>
<p style="padding-left: 30px">Shelly:<br />
plugin_name: shelly</p>
<p>Hier gibt es keinerlei Parameter.</p>
<p>Das Shelly Plugin wird über Item-Parameter getriggert, deshalb habe ich Folgendes in meinem Garagentor Item ergänzt:</p>
<p style="padding-left: 30px">Tor:<br />
name: Tor<br />
<strong><span style="color: #3366ff">shelly_id: 8CAAB505559E</span></strong><br />
<strong><span style="color: #3366ff">shelly_type: shelly1</span></strong><br />
<strong><span style="color: #3366ff">shelly_attr: relay</span></strong><br />
<strong><span style="color: #3366ff">shelly_relay: 0</span></strong><br />
enforce_updates: true<br />
type: bool<br />
sv_widget: &#8222;{{ basic.stateswitch(&#8218;item&#8216;, &#8218;item&#8216;, &#8218;midi&#8216;, 1, &#8220;, &#8220;, &#8220;, &#8218;blink&#8216;) }}&#8220;</p>
<p>(Hier hatte ich den Fehler gemacht und shelly_<strong><span style="color: #ff0000">ID</span></strong> definiert, was mich zwei Stunden gekostet hat)</p>
<p>Danach erscheint dann (fast) alles im Web-GUI.</p>
<p>Zunächst die Definitionen im Item:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug1-1024x311.png" alt="" class="alignnone wp-image-2530 size-large" width="750" height="228" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug1-1024x311.png 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug1-300x91.png 300w, https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug1-768x233.png 768w, https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug1.png 1046w" sizes="(max-width: 750px) 100vw, 750px" /></p>
<p>Ob der Broker läuft findet Ihr dann unter dem Tab: Broker Information:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug2-1024x383.png" alt="" class="alignnone size-large wp-image-2531" width="750" height="281" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug2-1024x383.png 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug2-300x112.png 300w, https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug2-768x287.png 768w, https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug2.png 1032w" sizes="(max-width: 750px) 100vw, 750px" /></p>
<p>wenn nicht, schaut bitte in Eure Konfiguration, ob MQTT enabled ist:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/05/mqtt1-1024x411.png" alt="" class="alignnone size-large wp-image-2533" width="750" height="301" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/05/mqtt1-1024x411.png 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/05/mqtt1-300x120.png 300w, https://www.smarthomeng.de/wp-content/uploads/2020/05/mqtt1-768x308.png 768w, https://www.smarthomeng.de/wp-content/uploads/2020/05/mqtt1.png 1054w" sizes="(max-width: 750px) 100vw, 750px" /></p>
<p>In der GUI des Shelly Plugin findet Ihr aber zunächst nichts, oder nur den <strong>Namen</strong> des Devices.</p>
<p>Jetzt geht&#8217;s wieder zur Shelly App um die Broker Verbindung zu konfigurieren. In der SmarthomeNG Konfiguration seht Ihr im letzten Screenshot, dass der MQTT Broker auf dem SmarthomeNG Rechner läuft und auf den Port 1883 hört. Das müsst Ihr jetzt noch dem Shelly Device beibringen. (In der Shelly App):</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/05/Config3.png" alt="" class="alignnone size-full wp-image-2529" width="880" height="824" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/05/Config3.png 880w, https://www.smarthomeng.de/wp-content/uploads/2020/05/Config3-300x281.png 300w, https://www.smarthomeng.de/wp-content/uploads/2020/05/Config3-768x719.png 768w" sizes="(max-width: 880px) 100vw, 880px" /></p>
<p>Zunächst müsst Ihr den haken bei &#8222;Enable action execution via MQTT&#8220; und dann noch unter Server: wo und wie er zu erreichen ist. (IP-Adresse des Raspi und Port 1883).</p>
<p>Selbstverständlich kann ich weiterhin mein Garagentor über die HTTP Logik im 1.5er System öffnen und auch über die Shelly App (hier aber nicht mehr über die Cloud, wie Ihr es in der WARNING findet)</p>
<p>Danach ist dann Eure Konfiguration komplett und das Shelly Device auch im Shelly Plugin zu finden:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug3-1024x326.png" alt="" class="alignnone size-large wp-image-2532" width="750" height="239" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug3-1024x326.png 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug3-300x96.png 300w, https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug3-768x245.png 768w, https://www.smarthomeng.de/wp-content/uploads/2020/05/shellyPlug3.png 1048w" sizes="(max-width: 750px) 100vw, 750px" /></p>
<p>Diese ganzen Zusammenhänge müssen erst mal verstanden werden, ehe man eine solche Konfiguration aufsetzen kann. Deshalb habe ich das hier mal zusammengestellt, weil das so nicht aus der Dokumentation hervor geht.</p>
<p>Viel Spaß mit Euren Shelly Devices. Wie Ihr andere Devices mit mehr Funktionen konfiguriert und wie ich sie über SmartVISU administriere, beschreibe ich (vielleicht) in weiteren Blogs.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/wie-ich-meinen-ersten-shelly-ueber-das-plugin-mit-mqtt-eingebunden-habe/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Neuerungen bei MQTT in SmartHomeNG v1.7</title>
		<link>https://www.smarthomeng.de/neuerungen-bei-mqtt-in-smarthomeng-v1-7</link>
					<comments>https://www.smarthomeng.de/neuerungen-bei-mqtt-in-smarthomeng-v1-7#respond</comments>
		
		<dc:creator><![CDATA[Martin Sinn]]></dc:creator>
		<pubDate>Sun, 05 Apr 2020 23:02:30 +0000</pubDate>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[MQTT]]></category>
		<category><![CDATA[shelly]]></category>
		<category><![CDATA[tasmota]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=2441</guid>

					<description><![CDATA[MQTT in SmartHomeNG ab v1.7 Bisher war in SmartHomeNG das eigentliche MQTT Protokoll im mqtt Plugin implementiert. In SmartHomeNG v1.7 wurde die Unterstützung des eigentlichen MQTT Protokolls in den Core verlagert. Die Implementierung erfolgte als ein ladbares Modul. Es gibt nun ein neues mqtt Plugin, welches die Protokoll Unterstützung des<a class="moretag" href="https://www.smarthomeng.de/neuerungen-bei-mqtt-in-smarthomeng-v1-7"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<h2>MQTT in SmartHomeNG ab v1.7</h2>
<p>Bisher war in SmartHomeNG das eigentliche MQTT Protokoll im mqtt Plugin implementiert.</p>
<p>In SmartHomeNG v1.7 wurde die Unterstützung des eigentlichen MQTT Protokolls in den Core verlagert. Die Implementierung erfolgte als ein ladbares Modul. Es gibt nun ein neues mqtt Plugin, welches die Protokoll Unterstützung des Core nutzt.</p>
<p>Diese Änderung bringt neue Funktionalitäten mit sich:</p>
<ul>
<li>Logiken können das MQTT Protokoll nutzen. Wie das genau geht, ist in der <a href="https://www.smarthomeng.de/user/logiken/mqtt_nutzung.html">Anwender Dokumentation</a> zu SmartHomeNG beschrieben.</li>
<li>Weitere Plugins können das MQTT Protokoll nutzen und darauf aufbauend Payload-Protokolle zu verschiedenen Devices implementieren, ohne das eigentliche MQTT Protokoll selbst implementieren zu müssen. Ein Beispiel hierfür ist das <strong>shelly Plugin,</strong> welches mit SmartHomeNG v1.7 hinzugekommen ist und die einfache Ansteuerung verschiedener Shelly Devices über MQTT ermöglicht. Details zu diesem Plugin sind in der <a href="https://www.smarthomeng.de/user/plugins/shelly/user_doc.html">Anwender Dokumentation</a> zu SmartHomeNG beschrieben.</li>
</ul>
<h3>Konfiguration des MQTT Moduls</h3>
<p>Durch die Verlagerung in den Core, ist auch die Konfiguration des MQTT Protokolls an eine andere Stelle gewandert. Die Konfiguration kann über die graphische Oberfläche oder direkt in der entsprechenden Konfigurationsdatei erfolgen:</p>
<p>In der GUI finden sich die Einstellungen unter System/Konfiguration im Tab <strong>MQTT Modul</strong>:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2020/03/Capto_Capture-2020-03-29_04-26-55_PM-300x219.jpg" alt="MQTT Konfiguration" width="675" height="493" class=" wp-image-2452" srcset="https://www.smarthomeng.de/wp-content/uploads/2020/03/Capto_Capture-2020-03-29_04-26-55_PM-300x219.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2020/03/Capto_Capture-2020-03-29_04-26-55_PM-768x560.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2020/03/Capto_Capture-2020-03-29_04-26-55_PM-1024x746.jpg 1024w, https://www.smarthomeng.de/wp-content/uploads/2020/03/Capto_Capture-2020-03-29_04-26-55_PM.jpg 1260w" sizes="(max-width: 675px) 100vw, 675px" /></p>
<p>&nbsp;</p>
<p>Damit die Konfiguration wirksam wird und das MQTT Modul beim Restart von SmartHomeNG geladen wird, muss der Parameter <strong>enabled</strong> auf <strong>true</strong> gesetzt werden.</p>
<p>Alternativ kann die Konfiguration direkt in der Datei <strong>../etc/module.yaml</strong> erfolgen. In der Datei muss ein Abschnitt <strong>mqtt:</strong> angelegt werden, der einen Eintrag <strong>module_name: mqtt</strong> enthält. In diesem Abschnitt können dann die Parameter konfiguriert werden.</p>
<p>Beispiel:</p>
<pre><code class="language-yaml">
mqtt:
    module_name: mqtt
    # broker_host: smarthomeng.local
    broker_monitoring: true
    # qos: 1
    # acl: ''
    last_will_topic: devices/shng-module/$online
    last_will_payload: 'False'
    birth_topic: devices/shng-module/$online
    birth_payload: 'True'
    # bool_values: ['Falsch', 'Wahr']
    # user: user
    # password: geheim
</code></pre>
<p>&nbsp;</p>
<h3>Konfiguration des MQTT Plugins</h3>
<p>Die Funktionalität, die das MQTT Plugin zur Verfügung stellte, gibt es weiterhin. Das MQTT Plugin ist entsprechend angepasst worden und nutzt zur Kommunikation jetzt die MQTT Unterstützung des Core. Das Plugin hat jedoch keine Parameter mehr, die konfiguriert werden müssten. Die Item Attribute (mqtt_topic, mqtt_topic_in, mqtt_topic_out, etc.) sind unverändert erhalten geblieben.</p>
<p>Eine Konfiguration des mqtt Plugins in der Plugin Konfigurationsdatei <strong>../etc/plugin.yaml</strong> sieht folgendermaßen aus:</p>
<pre><code class="language-yaml">
mqtt:
    plugin_name: mqtt

</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/neuerungen-bei-mqtt-in-smarthomeng-v1-7/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>RaspBee Gateway Bridge mit dem SmartHomeNG Plugin ‚HUE‘</title>
		<link>https://www.smarthomeng.de/raspbee-gateway-bridge-mit-dem-smarthomeng-plugin-hue</link>
					<comments>https://www.smarthomeng.de/raspbee-gateway-bridge-mit-dem-smarthomeng-plugin-hue#respond</comments>
		
		<dc:creator><![CDATA[Marcus Schulte]]></dc:creator>
		<pubDate>Tue, 04 Dec 2018 06:52:07 +0000</pubDate>
				<category><![CDATA[Beispiel-Implementierungen]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[ConBee]]></category>
		<category><![CDATA[Dresden Elektronik]]></category>
		<category><![CDATA[HUE]]></category>
		<category><![CDATA[hue2]]></category>
		<category><![CDATA[Phoscon]]></category>
		<category><![CDATA[RaspBee]]></category>
		<category><![CDATA[ZigBee]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=2260</guid>

					<description><![CDATA[Hallo, ich möchte Euch in diesem Blog die Implementierung der RaspBee Gateway Bridge von Dresden Elektronik mittels des HUE-Plugins vorstellen. Das Aufsatzmodul erweitert den Raspberry Pi um die ZigBee-Funktionalität und ermöglicht über die REST API Schnittstelle der deCONZ Applikation die direkte Kommunikation mit einer Vielzahl von ZigBee 3.0 bzw. ZigBee<a class="moretag" href="https://www.smarthomeng.de/raspbee-gateway-bridge-mit-dem-smarthomeng-plugin-hue"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<p>Hallo,</p>
<p>ich möchte Euch in diesem Blog die Implementierung der RaspBee Gateway Bridge von Dresden Elektronik mittels des HUE-Plugins vorstellen. Das Aufsatzmodul erweitert den Raspberry Pi um die ZigBee-Funktionalität und ermöglicht über die REST API Schnittstelle der deCONZ Applikation die direkte Kommunikation mit einer Vielzahl von ZigBee 3.0 bzw. ZigBee PRO Geräten, darunter beispielsweise Philips‘ Hue, die Vorschaltgeräteserie von Dresden Elektronik oder der XBee Serie 2. Die Kompatibilitätsliste der RaspBee Gateway Bridge findet Ihr <span><a href="https://www.dresden-elektronik.de/funktechnik/solutions/wireless-light-control/kompatibilitaet/">hier</a></span>.</p>
<p>In meinem Fall verwende ich die RaspBee Bridge in einem dezentralen Raspberry Pi 3 Model B um über das HUE-Plugin schaltbare Steckdosen (Osram Smart+ Plug und Paulmann Cephei Schaltcontroller) und vor allem mehrere RGB/W LED-Streifenlichter (24V mit 5050 SMD’s) mittels ZigBee LED Vorschaltgeräte (Funkvorschaltgerät FLS-PP lp von Dresden Elektronik) in SmarthomeNG einzubinden. Die Anzahl der ZigBee 3.0 Geräte wächst rasant und der Open Source REST-API Standard sorgt dafür das die Preise wettbewerbsfähig bleiben &#8211; Insofern sollten die hier erwähnten Geräte nur einen kleinen beispielhaften Ausschnitt darstellen, was (theoretisch) mit ZigBee Geräten und der RaspBee Bridge möglich ist.</p>
<p>Zu beachten ist, dass das SmarthomeNG HUE-Plugin nur auf Geräte aus dem „Licht“-Bereich zugreifen kann. ZigBee Geräte für Schalter und Sensoren lassen sich zwar in das RaspBee Gateway einbinden, aber nicht mit dem HUE-Plugin ansprechen (falls dem nicht so ist, lasst es mich bitte wissen).</p>
<p>Das System läuft jetzt bei mir seit über einem halben Jahr sehr stabil zusammen mit anderen Systemen (u.a. KNX, Sonos und MQTT) in SmarthomeNG bzw. SmartVISU &#8211; einschließlich des Widgets hue.control zur Farbsteuerung der LED Stripes. Die Reaktionszeit steht KNX in nichts nach.</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/12/ZigBee_Beispiel.jpg" alt="" width="720" height="475" class="alignleft size-full wp-image-2275" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/12/ZigBee_Beispiel.jpg 720w, https://www.smarthomeng.de/wp-content/uploads/2018/12/ZigBee_Beispiel-300x198.jpg 300w" sizes="(max-width: 720px) 100vw, 720px" /></p>
<p>Allerdings hatte ich noch nicht die Zeit mich mit allen Funktionalitäten zu befassen. Auf meiner ToDo – Liste steht u.a. noch die Konfiguration der Szenensteuerung.</p>
<p>&nbsp;</p>
<h4>Installation des Bridge-Moduls</h4>
<p>Die Installation der Bridge-Moduls selbst auf einem Raspberry Pi Model B (RasPi2 oder 3) wird von Dresden Elektronik gut beschrieben. Das Modul wird auf die GPIO Stiftleiste aufgesteckt. In meinem Fall habe ich den RasPi samt Modul als feste Installation im Erdgeschoss platziert und über LAN mit dem Netzwerk verbunden. Eine Verbindung über WLAN sollte genauso gehen, aber da ich die Möglichkeit einer LAN-Verkabelung hatte, wollte ich vermeiden das der WLAN Chip des RasPi das ZigBee Signal des benachbarten Bridge-Moduls stört, das nur mit einer Chip-Keramik-Antenne ausgestattet ist. Damit sollte zwar laut Datenblatt eine Reichweite von 500m (freies Feld) möglich sein, aber da die wenigsten von uns Ihr Bett im Kornfeld aufgestellt haben, kann im realen Betrieb nach einigen wenigen massiven Wänden schon Funkschatten entsteht. Nun übertragen die ZigBee Geräte die Signale jedoch nicht nur zentral zur Bridge sondern kommunizieren auch untereinander als sogenanntes Mesh-Netzwerk. Somit lösen sich solche Probleme mit steigender Anzahl von Geräten von selbst. Trotzdem habe ich mich wie bereits erwähnt entschieden LAN zu nutzen und WLAN und Bluetooth im Raspberry auszuschalten in dem man das Laden der Treiber verhindert.</p>
<p>&nbsp;</p>
<p>Wer es genauso machen möchte: Zuerst die Datei /etc/modprobe.d/raspi-blacklist.conf mit einem Editor bearbeiten. Dazu öffnet man die Konfigurationsdatei:</p>
<pre><code class="language-actionscript">sudo nano /etc/modprobe.d/raspi-blacklist.conf</code></pre>
<p>In der Datei die folgenden Treiber deaktivieren:<code class="language-actionscript"><br />
</code></p>
<pre><code class="language-markup"># WLAN abschalten
blacklist brcmfmac
blacklist brcmutil
#blacklist cfg80211
#blacklist rfkill
# Bluetooth abschalten
blacklist btbcm
blacklist hci_uart</code></pre>
<p>Anschließend speichern und schließen. Zusätzlich muss man noch einen Dienst abschalten, der sonst versucht Bluetooth zu nutzen.</p>
<pre><code class="language-markup">sudo systemctl disable hciuart</code></pre>
<p>Danach ist ein Neustart notwendig.</p>
<p>&nbsp;</p>
<h4>Installation der Applikationssoftware deCONZ</h4>
<p>Für das Aufsetzen des Raspbian Stretch selbst und der Applikationssoftware deCONZ (mit dem Namen der Software konnte ich mich nie anfreunden) für das eigentliche Bridge-Modul gibt es eine ziemlich gute Anleitung von <span><a href="https://www.dresden-elektronik.de/fileadmin/Downloads/Dokumente/Produkte/ZLL/RaspBee-BHB-en.pdf">Dresden Elektronik</a></span>.</p>
<p><u>Vor</u> der Installation von deCONZ habe ich einen eigenen User bzw. Usergruppen für SmarthomeNG anlegen. Ich habe mich dabei an die gleichen Einstellungen wie für die <span><a href="https://www.smarthomeng.de/user/installation/komplettanleitung_debian.html">Installation von SmarthomeNG</a></span> gehalten:</p>
<pre><code class="language-markup">sudo adduser smarthome --disabled-password --gecos "First Last,RoomNumber,WorkPhone,HomePhone"
sudo usermod -aG www-data,sudo smarthome
sudo usermod -aG www-data smarthome</code></pre>
<p>&nbsp;</p>
<p>Der Benutzer ‚smarthome‘ muss nun noch abgemeldet und neu angemeldet werden, damit die Rechte neu eingelesen werden. Dazu am besten das System neu booten mit:</p>
<pre><code class="language-markup">sudo poweroff</code></pre>
<p>&nbsp;</p>
<p>Nach der Installation von deConz sollte der ‚deCONZ systemd headless service‘ laufen und man kann über das RaspBee Gateway die einzelnen ZigBee Geräte anschließen.</p>
<p>&nbsp;</p>
<h4>Anmelden neuer ZigBee Geräte an der Bridge</h4>
<p>Das Hinzufügen und Einrichten neuer ZigBee Geräte geschieht am besten mit dem deCONZ Webinterface ‚<span><a href="https://www.dresden-elektronik.de/funktechnik/solutions/wireless-light-control/wireless-ballasts/?eID=dam_frontend_push&amp;docID=4620">Wireless Light Control WebApp</a></span>‘. Daneben gibt es noch eine sehr umfangreichere deCONZ GUI, die eher für Entwickler gedacht ist. Für die reine Einbindung neuer Geräte ist die GUI nicht notwendig.</p>
<p>Wichtig ist, dass die elektrische Installation der ZigBee Geräte erst nach der Anmeldung in der RaspBee Bridge erfolgt, da zum Anmelden der Abstand zwischen Gerät und Bridge nur max. 50 cm betragen darf. Wer vorher schon z.B. das LED Vorschaltgerät im Gebäude verdrahtet hat, muss nochmal zum Schraubenzieher greifen, um beide Geräte zueinander zu führen.</p>
<p>Das eigentliche Anmelden neuer Licht-Geräte ist relativ einfach. Im Webinterface (‚Settings‘) das ZigBee-Netzwerk der Bridge öffnen (‚Open Network‘; ‚Done‘) und dann kurz warten bis das neue Gerät (sofern es sich in unmittelbarer Nähe zur Bridge befindet!) in der Geräteübersicht auftaucht.</p>
<p>&nbsp;</p>
<h4>Einrichten des HUE-Plugins in SmarthomeNG</h4>
<p>Egal ob HUE-Beleuchtung oder ZigBee (Licht-) Gerät eines anderen Anbieters – durch das HUE-Plugin kann man auf die Bridge zugreifen und die Werte auslesen bzw. neu setzen.</p>
<p>Die Installation des HUE-Plugins für die RaspBee-Bridge erfolgt analog wie für eine HUE-Bridge und ist in der SHNG <span><a href="https://www.smarthomeng.de/user/plugins/hue/README.html">Anwenderdokumentation</a></span> ganz gut beschrieben, deshalb gehe ich hier nicht näher darauf ein.</p>
<p>Damit sich anschließend das HUE-Plugin mit der Bridge verbinden kann, muss sich SHNG als neue Applikation einmalig in der Bridge registrieren. Dazu wird in der plugin.conf (/usr/smarthome/etc/plugin.conf) ein beliebig wählbarer User-Token hue_user als Listenwert eingetragen:</p>
<pre><code class="language-yaml">HUE:
    class_name: HUE
    class_path: plugins.hue
    hue_user:
      - 38f625a739562a8bd261ab9c7f5e62c8
    hue_ip:
      - 192.168.178.99
    hue_port:
      - '80'
    cycle_lamps: 10
    cycle_bridges: 30
    default_transitionTime: '0.4'</code></pre>
<p>&nbsp;</p>
<p>Die User ID dient, wenn autorisiert, als API-Key für die Kommunikation zwischen SHNG und der RaspBee-Bridge.</p>
<p>Für das eigentliche Registrieren benötigt man noch die Methode sh.hue.authorizeuser(), die man in eine kleine Logik einbinden kann:</p>
<pre class="line-numbers"><code class="language-python">#!/usr/bin/env python3
# hue_autorisierung.py
# 1) Unlock Gateway in deCONZ Webapp (System Settings)
# 2) Start logic ('Hue_autorisierung')
sh.HUE.authorizeuser()</code></pre>
<p>Und so läuft die Registrierung ab:</p>
<ul>
<li>Das Webinterface ‚Wireless Light Control WebApp‘ der Bridge öffnen</li>
<li>Über Menu &gt; Settings &gt; ‚Unlock Gateway‘ auswählen (nicht mit ‚Open Network‘ verwechseln, das nur für das Hinzufügen von Geräten verwendet wird).</li>
<li>Innerhalb von 60 Sekunden muss jetzt die Autorisierungs-Logik (s.o.) ausgelöst werden.</li>
</ul>
<p>Alternativ kann man die User-ID auch mit einem Rest Client in der Bridge generieren und anschließend auslesen um sie in der plugin.conf einzutragen.</p>
<p>&nbsp;</p>
<h4>Aufbau der Items</h4>
<p>Der Aufbau der Items in SmarthomeNG erfolgt wie in der Anleitung zum HUE-Plugin beschrieben. Die benötigte hue_lamp_id der jeweiligen Lampen kann mit einem REST-Client (z.B. ‚Postman‘ als Chrome Plugin) aus der Bridge ausgelesen werden:</p>
<pre><code class="language-rest">GET &lt;IP.VON.RASPBEE&gt;/api/&lt;USER-ID&gt;/lights</code></pre>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/12/GET_Postman.jpg" alt="" width="792" height="692" class="alignleft size-full wp-image-2267" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/12/GET_Postman.jpg 792w, https://www.smarthomeng.de/wp-content/uploads/2018/12/GET_Postman-300x262.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2018/12/GET_Postman-768x671.jpg 768w" sizes="(max-width: 792px) 100vw, 792px" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Die Antwort vom RaspBee listet alle verbundenen Geräte der Kategorie /lights in der Reihenfolge auf wie sie für die hue_lamp_id in der Itemdefinition verwendet wird.</p>
<p>Ich weiß leider nicht wie ein HUE-Gateway die RGB/W Steuerung vornimmt, aber in der RaspBee-Bridge wird bei der Verwendung von RGB/W LED-Stripes (zumindest bei einigen LED Controllern) der RGB-Bereich und der W-Bereich als getrennte Lampen – ID ausgewiesen. Das macht die Erstellung der Items etwas aufwändig, aber funktioniert problemlos.</p>
<p>Am einfachsten definiert man die ‚System‘ Items (also alles, was nicht speziell einem Gerät zugeordnet wird) in einer separaten raspbee.yaml.</p>
<pre class="line-numbers"><code class="language-yaml">raspbee:
  bridge_0:
    # if hue_lamp_id and hue_bridge_id is not set, it is searched in a higher layer
    # all light control specfic items are defined in 'smartvisu.conf' or 'smartvisu.yaml'
    hue_bridge_id: 0

    bridge_name:
        type: str
        hue_listen: bridge_name

    zigbeechannel:
        type: num
        hue_listen: zigbeechannel

    mac:
        type: str
        hue_listen: mac

    dhcp:
        type: bool
        hue_listen: dhcp

    ipaddress:
        type: str
        hue_listen: ipaddress

    netmask:
        type: str
        hue_listen: netmask

    gateway:
        type: str
        hue_listen: gateway

    utc:
        type: str
        hue_listen: UTC

    localtime:
        type: str
        hue_listen: localtime

    timezone:
        type: str
        hue_listen: timezone

    whitelist:
        type: dict
        hue_listen: whitelist

    bridge_swversion:
        type: str
        hue_listen: bridge_swversion

    apiversion:
        type: str
        hue_listen: apiversion

    swupdate:
        type: dict
        hue_listen: swupdate

    linkbutton:
        type: bool
        hue_listen: linkbutton

    portalservices:
        type: bool
        hue_listen: portalservices

    portalconnection:
        type: str
        hue_listen: portalconnection

    portalstate:
        type: dict
        hue_listen: portalstate

    scene:
        type: str
        hue_send: scene
        enforce_updates: 'true'</code></pre>
<p>&nbsp;</p>
<p>Die Items der Geräte werden dann in der smartvisu.yaml definiert. Das angehängte Beispiel zeigt die Steuerung für ein RGB/W Vorschaltgerät, unterteilt in einen RGB Teil und den dazugehörigen Weiss-Teil.</p>
<pre class="line-numbers"><code class="language-yaml">obergeschoss:

    seperator_obergeschoss:
        name: Obergeschoss
        sv_page: seperator

    gallerie:
        name: Gallerie
        sv_page: room
        sv_img: light_indoor_og_1.svg

        skulptur_rgb:
            name: Wand (Skulptur)
            visu_acl: rw
            sv_blocksize: 3
            sv_widget: "{{ hue.control('item','item.power','item.reachable','item.col_r','item.col_g','item.col_b','item.alert','item.effect','item.bri','item.sat','item.hue') }}"
            hue_lamp_id: 2
            hue_bridge_id: 0
            hue_lamp_type: 0

            power_knx:
                type: bool
                value: 'true'
                knx_dpt: 1
                knx_send: 7/0/11
                knx_listen: 7/0/11
                knx_cache: 7/0/11

            power:
                type: bool
                hue_send: 'on'
                hue_listen: 'on'
                knx_dpt: 1
                knx_send: 7/0/23
                knx_listen: 7/0/23
                knx_cache: 7/0/23

            reachable:
                type: bool
                hue_listen: reachable

            ct:
                type: num
                hue_send: ct
                hue_listen: ct

            bri:
                type: num
                cache: 'on'
                hue_send: bri
                hue_listen: bri
                hue_transitionTime: '0.2'

                dim:
                    type: list
                    # knx_dpt = 3
                    # knx_listen = x/x/x
                    hue_dim_max: 255
                    hue_dim_step: 10
                    hue_dim_time: '0.2'

            sat:
                type: num
                cache: 'on'
                hue_send: sat
                hue_listen: sat

            col_r:
                type: num
                cache: 'on'
                hue_send: col_r

            col_g:
                type: num
                cache: 'on'
                hue_send: col_g

            col_b:
                type: num
                cache: 'on'
                hue_send: col_b

            hue:
                type: num
                cache: 'on'
                hue_send: hue
                hue_listen: hue
                hue_transitionTime: '0.2'

                dim:
                    type: list
                    # knx_dpt = 3
                    # knx_listen = x/x/x
                    hue_dim_max: 65535
                    hue_dim_step: 2000
                    hue_dim_time: '0.2'

            effect:
                type: str
                hue_send: effect
                hue_listen: effect

            alert:
                type: str
                hue_send: alert
                hue_listen: alert

            modeltype:
                type: str
                hue_listen: type

            lampname:
                type: str
                hue_listen: name

            modelid:
                type: str
                hue_listen: modelid

            swversion:
                type: str
                hue_listen: swversion

        skulptur_white:
            name: Wandskulptur Weiss
            sv_blocksize: 3
            hue_lamp_id: 3
            hue_bridge_id: 0
            hue_lamp_type: 0
            visu_acl: rw
            sv_widget: "{{ basic.stateswitch('item1', 'item.power', 'mini', '', '', '', '') }}{{ basic.slider('item2', 'item.bri') }}"

            power:
                type: bool
                hue_send: 'on'
                hue_listen: 'on'
                knx_dpt: 1
                knx_send: 7/0/23
                knx_listen: 7/0/23
                knx_cache: 7/0/23

            reachable:
                type: bool
                hue_listen: reachable

            bri:
                type: num
                cache: 'on'
                hue_send: bri
                hue_listen: bri
                hue_transitionTime: '0.2'

                dim:
                    type: list
                    # knx_dpt = 3
                    # knx_listen = x/x/x
                    hue_dim_max: 255
                    hue_dim_step: 10
                    hue_dim_time: '0.2'

            effect:
                type: str
                hue_send: effect
                hue_listen: effect

            alert:
                type: str
                hue_send: alert
                hue_listen: alert

            modeltype:
                type: str
                hue_listen: type

            lampname:
                type: str
                hue_listen: name

            modelid:
                type: str
                hue_listen: modelid

            swversion:
                type: str
                hue_listen: swversion</code></pre>
<p>&nbsp;</p>
<h4>Nachtrag</h4>
<p>Die Anzahl der ZigBee Geräte nimmt wie schon erwähnt rasant zu. Am Anfang waren es hauptsächlich (LED)-Lampen und Leuchten wie z.B. das Phillips HUE Programm. Das HUE Plugin in SmarthomeNG deckt das sehr schon ab und damit lässt sich alles steuern. Mittlerweile erlauben die Gateway Bridges der verschiedenen Hersteller aber auch die Kommunikation mit ZigBee Schaltern und Sensoren (Temperatur, Feuchtigkeit, Bewegungsmelder, Rauchmelder, Luftqualität, etc.). Leider scheint das HUE-Plugin dafür nicht ausgelegt zu sein, so dass sich die Anwendung auf den Bereich ‚Licht schalten‘ beschränkt. Langfristig würde wahrscheinlich ein Plugin Sinn machen das alle Applikationen des RaspBee aus dem ZigBee 3.0 Bereich abdeckt.</p>
<p>&nbsp;</p>
<p>TODO:</p>
<ul>
<li>Implementierung der Szenensteuerung</li>
<li>Integration von ZigBee Sensoren (z.B aus der Xiaomi-Serie)</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/raspbee-gateway-bridge-mit-dem-smarthomeng-plugin-hue/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AWS für das Alexa Plugin einrichten</title>
		<link>https://www.smarthomeng.de/aws-fuer-das-alexa-plugin-einrichten</link>
					<comments>https://www.smarthomeng.de/aws-fuer-das-alexa-plugin-einrichten#comments</comments>
		
		<dc:creator><![CDATA[Marc René Frieß]]></dc:creator>
		<pubDate>Thu, 29 Nov 2018 17:15:15 +0000</pubDate>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Alexa]]></category>
		<category><![CDATA[alexa4p3]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda-Funktion]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=2207</guid>

					<description><![CDATA[Mit dem Alexa Plugin ist es möglich, SmartHomeNG Items über Alexa zu steuern. Um das Plugin einzurichten, müssen allerdings zuerst einige Dinge auf der Plattform Amazon Web Services (AWS) eingerichtet werden. Dieser Artikel ist Work in Progress und wird nach und nach die Alexa Doku im README des Plugins und<a class="moretag" href="https://www.smarthomeng.de/aws-fuer-das-alexa-plugin-einrichten"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<p>Mit dem Alexa Plugin ist es möglich, SmartHomeNG Items über Alexa zu steuern. Um das Plugin einzurichten, müssen allerdings zuerst einige Dinge auf der Plattform Amazon Web Services (AWS) eingerichtet werden.</p>
<p>Dieser Artikel ist Work in Progress und wird nach und nach die Alexa Doku im <a href="https://github.com/smarthomeNG/plugins/tree/master/alexa" target="_blank" rel="noopener">README des Plugins</a> und im KNX-User-Forum (<a href="https://knx-user-forum.de/forum/supportforen/smarthome-py/1021150-amazon-alexa-plugin" target="_blank" rel="noopener">https://knx-user-forum.de/forum/supportforen/smarthome-py/1021150-amazon-alexa-plugin</a>) ablösen. Ein Teil der Originalanleitung war zudem unter <a href="https://developer.amazon.com/de/blogs/post/Tx4WG410EHXIYQ/Five-Steps-Before-Developing-a-Smart-Home-Skill" target="_blank" rel="noopener">https://developer.amazon.com/de/blogs/post/Tx4WG410EHXIYQ/Five-Steps-Before-Developing-a-Smart-Home-Skill</a> dokumentiert.</p>
<p>Zuerst muss unter <a href="https://developer.amazon.com/home.html" target="_blank" rel="noopener">https://developer.amazon.com/home.html</a> ein Entwicklerzugang erstellt werden. Trotz später notwendiger Angabe einer Kreditkarte kann davon ausgegangen werden, dass die anfallenden Request bei normaler Nutzung deutlich unterhalb der Grenze für die &#8222;Free Tier&#8220; bleiben werden. Trotzdem sollte man gelegentlich im Billing nachsehen. Auch ist zu empfehlen, den Zugang als 2-Factor-Authentifizierung einzurichten, anstatt das auch im &#8222;Shopping&#8220; Amazon verwendete Passwort alleine zu verwenden!</p>
<h1>OAuth2 Credentials anlegen</h1>
<p>Über <a href="https://developer.amazon.com/home.html" target="_blank" rel="noopener">https://developer.amazon.com/home.html</a> &#8211;&gt; &#8222;Login with Amazon&#8220; muss zuerst via &#8222;Create a New Security Profile&#8220; ein neues Security Profile erzeugt werden.</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/11/lws.jpg" alt="" width="1377" height="315" class="alignnone size-full wp-image-2219" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/11/lws.jpg 1377w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lws-300x69.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lws-768x176.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lws-1024x234.jpg 1024w" sizes="(max-width: 1377px) 100vw, 1377px" /></p>
<p>Hier sind ein Name, eine Beschreibung und ein Link auf eine &#8222;privacy.htm&#8220; Seite (bspw. via Dyndns &#8211; die Seite muss meines Wissens nicht erreichbar sein) anzugeben.</p>
<p>Über den Reiter Web Settings kann man nun noch seine Client ID und seinen Client Secret einsehen, die für den nächsten Schritt notiert werden müssen. Im unten stehenden Screenshot sind die Informationen entfernt worden:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/11/lws_clientdaten.png" alt="" width="1381" height="629" class="alignnone size-full wp-image-2220" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/11/lws_clientdaten.png 1381w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lws_clientdaten-300x137.png 300w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lws_clientdaten-768x350.png 768w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lws_clientdaten-1024x466.png 1024w" sizes="(max-width: 1381px) 100vw, 1381px" /></p>
<h1>Alexa Skill anlegen</h1>
<p>Als Nächstes muss im Alexa Entwicklerportal ein neuer Skill angelegt werden. Hierzu unter <a href="https://developer.amazon.com/alexa/console/ask" target="_blank" rel="noopener">https://developer.amazon.com/alexa/console/ask</a> &#8222;Create Skill&#8220; auswählen.</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_developer_overview.jpg" alt="" width="1304" height="601" class="alignnone size-full wp-image-2212" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_developer_overview.jpg 1304w, https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_developer_overview-300x138.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_developer_overview-768x354.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_developer_overview-1024x472.jpg 1024w" sizes="(max-width: 1304px) 100vw, 1304px" /></p>
<p>Hier ist die korrekte geographische Region als Default Endpoint zu wählen (in meinem Fall eu-west bzw. Europe/India). Als Payload ist für die alten Version des Plugins v2 zu wählen, für die aktuell in Entwicklung befindliche neue (derzeit noch nicht im DEV Branch, dafür unter <a href="https://github.com/Andrek01/Alexa4PayloadV3" target="_blank" rel="noopener">https://github.com/Andrek01/Alexa4PayloadV3</a>) v3.</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_skill.png" alt="" width="1369" height="1044" class="alignnone size-full wp-image-2213" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_skill.png 1369w, https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_skill-300x229.png 300w, https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_skill-768x586.png 768w, https://www.smarthomeng.de/wp-content/uploads/2018/11/alexa_skill-1024x781.png 1024w" sizes="(max-width: 1369px) 100vw, 1369px" /></p>
<p><strong>Wichtig:</strong> Das was neben &#8222;amzn1.ask.skill.&#8220; bei &#8222;<span>Your Skill ID&#8220; steht, kopieren. Diese UUID wird später für den nächsten Schritt (Lambda-Funktion) benötigt!</span></p>
<p>Unter Account Linking sind nun die OAuth2 Daten zu hinterlegen, die im vorherigen Schritt generiert wurden:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/11/account_linking-1.png" alt="" width="1384" height="1278" class="alignnone size-full wp-image-2216" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/11/account_linking-1.png 1384w, https://www.smarthomeng.de/wp-content/uploads/2018/11/account_linking-1-300x277.png 300w, https://www.smarthomeng.de/wp-content/uploads/2018/11/account_linking-1-768x709.png 768w, https://www.smarthomeng.de/wp-content/uploads/2018/11/account_linking-1-1024x946.png 1024w" sizes="(max-width: 1384px) 100vw, 1384px" /></p>
<h1>Lambda-Funktion anlegen.</h1>
<p>Um Aktionen gegen SmartHomeNG ausführen zu können, muss über <a href="https://aws.amazon.com" target="_blank" rel="noopener">https://aws.amazon.com</a> (und dann in die AWS Management Console gehen) eine sog. Lambda-Funktion angelegt werden (Link Compute -&gt; Lambda).</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda.jpg" alt="" width="1157" height="681" class="alignnone size-full wp-image-2246" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda.jpg 1157w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda-300x177.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda-768x452.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda-1024x603.jpg 1024w" sizes="(max-width: 1157px) 100vw, 1157px" /></p>
<p>Legt man diese über &#8222;Funktion erstellen&#8220; an, müssen ein Name (bspw. SmartHomeNGFunction), eine Laufzeitumgebung (Node.js 8.10) und eine Vorhandene Rollen (lambda_basic_execution) gewählt werden.</p>
<p>Der neu erstellten Lambda-Funktion wird nun ein Alexa Smart Home Skill zugeordnet. Klickt man diesen unter &#8222;Auslöser hinzufügen&#8220; an, so gibt man nun die Anwendungs-ID (die UUID aus dem vorherigen Schritt) ein! Der Auslöser wird als aktiviert gesetzt!</p>
<p>Das Ganze ist in unten stehendem Screenshot zu sehen.</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda-1.png" alt="" width="1348" height="3065" class="alignnone size-full wp-image-2251" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda-1.png 1348w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda-1-132x300.png 132w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda-1-768x1746.png 768w, https://www.smarthomeng.de/wp-content/uploads/2018/11/lambda-1-450x1024.png 450w" sizes="(max-width: 1348px) 100vw, 1348px" />Als Code muss folgendes eingetragen werden:</p>
<pre><code class="language-javascript">
/*
You need to specify the following environmental variables in the lambda function:
- SMARTHOME_HOST
		foobar.dyndns.tld
- SMARTHOME_PORT
		443 - endpoint must be https enabled!
- SMARTHOME_PATH
		'/'
- SMARTHOME_AUTH
		'user:password'
*/
exports.handler = function(event, context, callback) {
	var data = JSON.stringify(event)

	var options = {
		hostname: process.env.SMARTHOME_HOST,
		port: process.env.SMARTHOME_PORT,
		path: process.env.SMARTHOME_PATH,
		method: 'POST',
		auth: process.env.SMARTHOME_AUTH,
		headers: {
			'Content-Type': 'application/json',
			'Content-Length': Buffer.byteLength(data)
		}
	};

	var https = require('https');
	var req = https.request(options, (res) =&gt; {
		console.log(`HTTP ${res.statusCode}`);
		res.setEncoding('utf8');

		var responseData = '';
		res.on('data', (dataChunk) =&gt; {
		    responseData += dataChunk
		});
		res.on('end', () =&gt; {
			console.log('raw response:', responseData)

			var response = JSON.parse(responseData);
			if (res.statusCode == 200) {
				console.info('OK', JSON.stringify(response))
				callback(null, response);
			} else {
				console.error('Failed', JSON.stringify(response))
				callback('DependentServiceUnavailableError');
			}
		});
	});
	req.on('error', (e) =&gt; {
		console.error('request failed', e);
		callback(e);
	});

	console.log('requesting', data)
	req.write(data);
	req.end();
}
</code></pre>
<p>Unterhalb des Codeblocks sind nun noch die vier Variablen SMARTHOME_AUTH (im Stil &lt;user&gt;:&lt;passwort&gt;), SMARTHOME_HOST, SMARTHOME_PATH und SMARTHOME_PORT zu definieren. Wird ein ReverseProxy mit HTTPS verwendet (siehe bspw. <a href="https://www.smarthomeng.de/nginx-als-reverseproxy">im Artikel NGINX als ReverseProxy</a>), so sollte der User und das Passwort dort als Basic Authentication gesetzt werden. Der ReverseProxy muss in Folge dann eine Weiterleitung auf das SmartHomeNG Alexa Plugin (SmartHomeNG URL und Alexa Port) definieren. Port wäre in diesem Fall 443 (https) und URL die Dyndns URL über die das Heimnetzwerk erreichbar ist.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/aws-fuer-das-alexa-plugin-einrichten/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Nutzen des UZSU Plugins für eine detaillierte Lichtkurvensteuerung</title>
		<link>https://www.smarthomeng.de/using-the-uzsu-plugin-for-advanced-light-control</link>
					<comments>https://www.smarthomeng.de/using-the-uzsu-plugin-for-advanced-light-control#respond</comments>
		
		<dc:creator><![CDATA[onkelandy]]></dc:creator>
		<pubDate>Tue, 11 Sep 2018 11:49:55 +0000</pubDate>
				<category><![CDATA[develop]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Automatik]]></category>
		<category><![CDATA[Licht]]></category>
		<category><![CDATA[Lichtkurven]]></category>
		<category><![CDATA[light]]></category>
		<category><![CDATA[schedule]]></category>
		<category><![CDATA[uzsu]]></category>
		<category><![CDATA[Zeitplan]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=2081</guid>

					<description><![CDATA[Für eine einfache Einführung in das Plugin lesen Sie bitte den anderen Blogartikel über die Steuerung von Rollläden. Ab UZSU Plugin Version 1.5.2 und smartVISU 2.9 Commit 5d15a36 (Stand Ende August 2018) gibt es eine neue Funktion im Universal Time Scheduler Plugin, mit der man eine Interpolation zwischen den angegebenen<a class="moretag" href="https://www.smarthomeng.de/using-the-uzsu-plugin-for-advanced-light-control"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<p>Für eine einfache Einführung in das Plugin lesen Sie bitte den anderen Blogartikel über die <a href="https://www.smarthomeng.de/using-the-uzsu-plugin-to-automate-blinds">Steuerung von Rollläden</a>.</p>
<p>Ab UZSU Plugin Version 1.5.2 und smartVISU 2.9 Commit 5d15a36 (Stand Ende August 2018) gibt es eine neue Funktion im Universal Time Scheduler Plugin, mit der man eine Interpolation zwischen den angegebenen Zeitpunkten einstellen kann. Dies ist besonders nützlich, wenn Sie circadiane Lichtkurven für warmweißes und kaltweißes Licht programmieren möchten, kann aber auch für RGB-LEDs nützlich sein.</p>
<p><strong>Hinweis</strong>: Bei aktivierter Interpolation interpoliert das Plugin ständig und sendet Werte im angegebenen Intervall, auch über Mitternacht. Wenn Sie Ihr Licht z.B. nur zwischen 20 Uhr (0%) und 21 Uhr (100%) dimmen wollen, müssen Sie einen zusätzlichen Wert um 21.01 Uhr (0%) einstellen. Andernfalls wird das Licht zwischen heute 21 Uhr und morgen 20 Uhr nur langsam gedimmt.</p>
<p>Unten sehen Sie ein Beispiel, wie das Widget von Stefan Widmer in smartVISU aussieht:</p>
<div id="attachment_2083" style="width: 760px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2083" src="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light-1024x505.png" alt="UZSU Graph" width="750" height="370" class="size-large wp-image-2083" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light-1024x505.png 1024w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light-300x148.png 300w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light-768x379.png 768w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light.png 1800w" sizes="(max-width: 750px) 100vw, 750px" /><p id="caption-attachment-2083" class="wp-caption-text">UZSU Graph widget mit Lichtkurven</p></div>
<p>Die obere rote Kurve zeigt den Verlauf des warmweißen Lichts über einen Tag (24 Stunden). Es gibt mehrere Punkte, die durch einfaches Anklicken der spezifischen x,y-Koordinaten im Diagramm festgelegt werden können. Die blauen Punkte sind &#8222;Standard&#8220;-Zeiteinstellungen um ca. Mitternacht, 5 Uhr, 8 Uhr, 18 Uhr und 21 Uhr. Der gelbe Punkt bezieht sich auf den Sonnenaufgang, der orangefarbene auf den Sonnenuntergang. Mit den Griffen neben diesen Punkten können Sie die &#8222;frühesten&#8220; und &#8222;spätesten&#8220; Werte durch Ziehen ändern.</p>
<p>Die untere blaue Kurve zeigt die Werte für das kalte weiße Licht. Die Punkte sind fast zu den gleichen Zeitpunkten gesetzt wie für das warmweiße Licht, allerdings mit Spitzenwerten am Morgen und am frühen Abend. Beide Kurven sind im Moment auf kubische Interpolation eingestellt. Sie können die Interpolation jedoch in der oberen rechten Ecke auf keine oder lineare Interpolation ändern. Um alle UZSU-Einstellungen für ein Element zu deaktivieren, klicken Sie auf das Kontrollkästchen in der oberen linken Ecke. Um einige Werte separat zu deaktivieren, klicken Sie auf diese und deaktivieren Sie die Schaltfläche &#8222;Akt/Act&#8220; (siehe unten). Inaktive Einträge werden in der Grafik als Rauten dargestellt, inaktive Elemente sind ausgegraut.</p>
<p>Um bestehende Einstellungen zu ändern, können Sie einfach die entsprechenden Punkte im Diagramm ziehen. Wenn Sie auf einen bestehenden Punkt klicken, können Sie weitere Details für sonnenabhängige Zeiten ändern oder die Einstellung nur für bestimmte Wochentage gelten lassen. Wenn Sie dies tun, wird das Diagramm wie unten dargestellt aktualisiert, wobei am Wochenende das Licht während der Nacht heller bleibt:</p>
<div id="attachment_2086" style="width: 760px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2086" src="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_week-1024x249.png" alt="UZSU Graph" width="750" height="182" class="size-large wp-image-2086" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_week-1024x249.png 1024w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_week-300x73.png 300w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_week-768x187.png 768w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_week.png 1646w" sizes="(max-width: 750px) 100vw, 750px" /><p id="caption-attachment-2086" class="wp-caption-text">UZSU Graph widget mit Lichtkurven für die ganze Woche</p></div>
<p>Das Einfügen des Diagramm-Widgets in Ihre smartVISU ist ziemlich einfach:</p>
<pre><code class="language-twig">
{{ device.uzsugraph('graph', 'coldwhite.uzsu', 'cold white', 1, 'num', [0, 255, 5]) }}</code></pre>
<p>Natürlich ist es auch möglich, das uzsuicon-Widget zu verwenden, um die Timings auf eine weniger grafische Weise zu konfigurieren. Implementieren Sie das als:</p>
<pre><code class="language-twig">
{{ device.uzsuicon('icon', 'coldwhite.uzsu', 'cold white', '', '', 'num') }}</code></pre>
<p>Wenn Sie auf das Symbol klicken, öffnet sich ein Popup-Fenster (siehe unten):</p>
<div id="attachment_2088" style="width: 562px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2088" src="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_popup-1024x939.png" alt="uzsu_popup" width="552" height="506" class=" wp-image-2088" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_popup-1024x939.png 1024w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_popup-300x275.png 300w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_popup-768x704.png 768w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_light_popup.png 1342w" sizes="(max-width: 552px) 100vw, 552px" /><p id="caption-attachment-2088" class="wp-caption-text">UZSU Graph widget popup für Lichter</p></div>
<p>Die Funktionsweise dieses Widgets wird in der smartVISU-Dokumentation und im Blogeintrag über die <a href="https://www.smarthomeng.de/using-the-uzsu-plugin-to-automate-blinds">Verwendung der UZSU zur Rolladensteuerung</a> näher beschrieben. In diesem Blogeintrag wird auch die Funktion &#8222;Zurück in der Zeit&#8220;, die Sie unten links sehen, näher erläutert. Außerdem sehen Sie in diesem Artikel, wie Sie Ihre Einträge für das UZSU-Plugin einrichten.</p>
<p>Um einen UZSU-Eintrag über die Logik zu aktualisieren, können Sie die folgenden Funktionen verwenden:</p>
<pre><code class="python">
# query the next scheduled value and time
sh.coldwhite.uzsu.planned()

# query the interpolation settings
sh.coldwhite.uzsu.interpolation()

# query whether the uzsu is set active or not
sh.coldwhite.uzsu.activate()

# set the uzsu active or inactive
sh.coldwhite.uzsu.activate(True/False)

# set interpolation options
sh.coldwhite.uzsu.interpolation(type='linear/none/cubic', interval=5, backintime=0)

# clear your settings of the uzsu item. BE CAREFUL!
sh.coldwhite.uzsu.clear(True)
</code></pre>
<p>Diese Funktionen können auch für einige einfache Logiken wie in diesem Beispiel verwendet werden:</p>
<p>Sie möchten ein bestimmtes Licht (z.B. Weihnachtsdekoration) zu einer bestimmten Zeit einschalten. Wenn Sie das Haus verlassen, möchten Sie dieses Licht ausschalten. Bei der Rückkehr nach Hause soll es (nur) dann wieder eingeschaltet werden, wenn die UZSU es in der Zwischenzeit nicht ausgeschaltet hätte:</p>
<pre><code class="python">
uzsustatus = sh.light.uzsu.planned()
if (uzsustatus['value'] == 0) and (sh.light.uzsu.activate() == True):
    sh.light(1)
</code></pre>
<p>Seit smarthomgeNG 1.6.1 kann dies noch einfacher mit der Funktion lastvalue() erreicht werden:</p>
<pre><code class="python">
sh.light(sh.light.uzsu.lastvalue())<span style="color: #3c4858;font-family: Roboto, Helvetica, Arial, sans-serif"><span>
</span></span></code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/using-the-uzsu-plugin-for-advanced-light-control/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Nutzen des UZSU Plugins zum automatischen Schalten von Rollläden</title>
		<link>https://www.smarthomeng.de/using-the-uzsu-plugin-to-automate-blinds</link>
					<comments>https://www.smarthomeng.de/using-the-uzsu-plugin-to-automate-blinds#comments</comments>
		
		<dc:creator><![CDATA[onkelandy]]></dc:creator>
		<pubDate>Sat, 08 Sep 2018 09:09:33 +0000</pubDate>
				<category><![CDATA[develop]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Automatik]]></category>
		<category><![CDATA[blinds]]></category>
		<category><![CDATA[Jalousien]]></category>
		<category><![CDATA[Rolladen]]></category>
		<category><![CDATA[schedule]]></category>
		<category><![CDATA[uzsu]]></category>
		<category><![CDATA[Zeitplan]]></category>
		<category><![CDATA[Zeitreihen]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=2062</guid>

					<description><![CDATA[Einleitung Das UZSU-Plugin ist nützlich, um bestimmte Werte für Ihre Artikel zu bestimmten Zeiten einzustellen. Durch die Möglichkeit, auch Sonnenauf- und -untergangsberechnungen einzubeziehen, können Sie zum Beispiel eine ganz einfache Steuerung Ihrer Jalousien erstellen. Die Konfiguration des Plugins ist sehr einfach, da es keine spezifischen Parameter zu setzen gibt. Dennoch<a class="moretag" href="https://www.smarthomeng.de/using-the-uzsu-plugin-to-automate-blinds"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<h5>Einleitung</h5>
<p>Das UZSU-Plugin ist nützlich, um bestimmte Werte für Ihre Artikel zu bestimmten Zeiten einzustellen. Durch die Möglichkeit, auch Sonnenauf- und -untergangsberechnungen einzubeziehen, können Sie zum Beispiel eine ganz einfache Steuerung Ihrer <strong>Jalousien</strong> erstellen.</p>
<p>Die Konfiguration des Plugins ist sehr einfach, da es keine spezifischen Parameter zu setzen gibt. Dennoch müssen Sie ein Element erstellen, in dem Ihr automatischer Zeitplan im Cache gespeichert werden soll. Der einfachste Weg, dies zu tun, ist die Erstellung eines untergeordneten Objekts mit relativer Referenzierung wie unten dargestellt. So können Sie dieses Objekt einfach in alle Objekte kopieren, die den UZSU verwenden sollen. Dieses Element muss auch ein uzsu_item-Attribut haben, das definiert, welches Element geändert werden soll. Sie können auch einfach die neue struct-Funktion verwenden und auf struct verweisen: <strong>uzsu.child</strong></p>
<pre><code class="language-yaml">
# items/my.yaml
someroom:

    blind1:
        type: num

        uzsu:
            type: dict
            uzsu_item: ..
            cache: 'True'
   blind2:
        type: num
        struct: uzsu.child
</code></pre>
<h5>smartVISU</h5>
<p>Sie können Ihre Zeiten und Werte mit Hilfe einer Logik einstellen (siehe <a href="https://www.smarthomeng.de/user/plugins/uzsu/user_doc.html">UZSU Doku</a>), aber es ist viel bequemer, das UZSU-Widget in smartVISU (2.9 oder neuer) zu verwenden.</p>
<p>Fügen Sie einfach ein Icon zu Ihrem Visu hinzu. Wenn Sie auf das Icon klicken, öffnet sich ein Popup, mit dem Sie Ihre universelle Zeitschaltuhr konfigurieren können.</p>
<pre><code class="language-twig">
{{ device.uzsuicon('uzsu_example', 'someroom.blind1.uzsu', 'Markise', '', '', 'num') }}
</code></pre>
<p>&nbsp;</p>
<div id="attachment_2064" style="width: 760px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2064" src="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_markise-1024x953.png" alt="uszu_blinds" width="750" height="698" class="size-large wp-image-2064" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_markise-1024x953.png 1024w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_markise-300x279.png 300w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_markise-768x715.png 768w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_markise.png 1332w" sizes="(max-width: 750px) 100vw, 750px" /><p id="caption-attachment-2064" class="wp-caption-text">VISU Widget Screenshot, der das Einstellen von automatisierten Rollläden zeigt</p></div>
<p>Schauen wir uns an, was mit dem obigen (leicht gephotoshoppten) Konfigurations-Popup passiert:</p>
<p>Während der Woche:</p>
<ul>
<li>Die Jalousien öffnen sich (Wert 0) 30 Minuten nach Sonnenaufgang, aber nie vor 7.00 Uhr und nie später als 8.00 Uhr.</li>
<li>Die Jalousien werden bei Sonnenuntergang geschlossen (Wert 100), jedoch nie vor 20.00 Uhr und nie später als 22.00 Uhr.</li>
</ul>
<p>An Wochenenden:</p>
<ul>
<li>Die Jalousien werden um 8.00 Uhr morgens geöffnet (Wert 0).</li>
<li>Die Jalousien können um 21.00 Uhr fast geschlossen werden (Wert 80), sobald die Schaltfläche &#8222;Akt&#8220; (aktiv) neben der Zeile aktiviert ist.</li>
<li>Abends um 23 Uhr werden die Jalousien geschlossen (Wert 100).</li>
</ul>
<h5>Nachholen von verpassten UZSU-Einträgen</h5>
<p><strong>Hinweis</strong>: Die in diesem Abschnitt beschriebene &#8222;Zurück in der Zeit&#8220; bzw. &#8222;back in time&#8220;-Funktionalität ist erst seit der SmartHomeNG-Version v1.6 verfügbar.</p>
<p>Ein Nachteil der UZSU, insbesondere im Vergleich zum Autoblind-Plugin, ist, dass ein Wert möglicherweise nicht gesetzt wird, wenn smarthomeNG in diesem Zeitraum nicht verfügbar ist. Wenn Sie z.B. an einem Wochenende um 7.59 Uhr neu starten, bleiben die Jalousien unten, da der UZSU-Eintrag für 8.00 Uhr höchstwahrscheinlich nicht ausgelöst wird. An dieser Stelle kommt die Funktion &#8222;Zurück in der Zeit&#8220; ins Spiel. Hier können Sie einen Zeitrahmen in Minuten festlegen, in dem das Plugin bei der Initialisierung zurückgehen soll, um einen Auslöser zu finden. Im vorliegenden Beispiel würde ein Wert von 10 Minuten ausreichen, um den Auslöser &#8222;0&#8220; zu finden, der um 8 Uhr morgens gesetzt worden wäre. Bei einer so einfachen Einrichtung könnten Sie die &#8222;Rückwärtszeit&#8220; auf mehrere Stunden erhöhen (z. B. 240 Minuten), aber beachten Sie, dass die Funktion in einer komplexeren Situation mit Bewertungen, Auslösern usw. zu seltsamen Situationen führen könnte.</p>
<h5>Nächste Schritte&#8230;</h5>
<p>Wenn Sie weiter gehen und Sonnenverfolgung, Wetterinformationen usw. einbeziehen möchten, empfiehlt sich die Verwendung des Plugins <a href="https://www.smarthomeng.de/starting-with-state-machine-automation-autoblind-plugin">autoblind/stateengine</a>. Sie können aber auch beide Plugins kombinieren.</p>
<p>Ein Beispiel wäre, das Licht tagsüber nach einer bestimmten Lichtkurve einzustellen (siehe Interpolationsfunktion), es aber nachts auf einen konstant niedrigen Wert zu ändern, sobald alle im Bett sind.</p>
<p>Ein anderes Beispiel wäre, die min_time und max_time aus dem Zustand des Autoblind-Plugins durch ein boolsches Element zu ersetzen (z.B. activate_state_x) und die UZSU zu verwenden, um dieses Element aktiv oder nicht aktiv zu setzen. Dies ist einfach ein bequemer und visueller Weg, um die minimale und maximale Zeit für Ihre Zustände festzulegen.</p>
<p>Schauen Sie sich das viel ausführlichere Beispiel zur <a href="https://www.smarthomeng.de/using-the-uzsu-plugin-for-advanced-light-control">Automatisierung Ihrer Beleuchtung mit der UZSU</a> an.</p>
<p>In SmarthomeNG 1.9, Plugin Version 1.6 wird eine neue Funktion namens &#8222;Zeitreihen&#8220; eingeführt. Damit können Sie wiederkehrende Einstellungen von Werten basierend auf von &#8211; bis Zeiteinstellungen oder einer bestimmten Anzahl von Wiederholungen festlegen. Bei der Angabe von Wiederholungen werden immer die nächsten 24 Stunden ab der Startzeit herangezogen. Zusätzlich sind sonnenbasierte Zeitreihen möglich. Es wird dringend empfohlen, das smartVISU Widget dafür zu verwenden, wie im Screenshot unten zu sehen.</p>
<div id="attachment_2749" style="width: 760px" class="wp-caption aligncenter"><a href="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_timeseries.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2749" src="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_timeseries-1024x508.png" alt="" width="750" height="372" class="size-large wp-image-2749" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_timeseries-1024x508.png 1024w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_timeseries-300x149.png 300w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_timeseries-768x381.png 768w, https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_timeseries.png 1330w" sizes="(max-width: 750px) 100vw, 750px" /></a><p id="caption-attachment-2749" class="wp-caption-text">VISU Beispiel für Zeitreihen<span style="font-size: 18px"></span></p></div>
<p><a href="https://www.smarthomeng.de/wp-content/uploads/2018/09/uzsu_timeseries.png"></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/using-the-uzsu-plugin-to-automate-blinds/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Google Maps Widget für SmartVISU 2.9</title>
		<link>https://www.smarthomeng.de/google-maps-widget-fuer-smartvisu-2-9</link>
					<comments>https://www.smarthomeng.de/google-maps-widget-fuer-smartvisu-2-9#respond</comments>
		
		<dc:creator><![CDATA[Marc René Frieß]]></dc:creator>
		<pubDate>Sat, 18 Aug 2018 14:52:28 +0000</pubDate>
				<category><![CDATA[Beispiel-Implementierungen]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[egigeozone]]></category>
		<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[smartVISU]]></category>
		<category><![CDATA[smartVISU 2.9]]></category>
		<category><![CDATA[Traffic Plugin]]></category>
		<category><![CDATA[Widget]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=1995</guid>

					<description><![CDATA[Auch in der Visualisierung kann es von Nutzen sein, seine aktuelle Position und ggf. eine Fahrtroute auf einer Google Maps Karte zu visualisieren. SmartHomeNG bietet eine Reihe an Plugins und Möglichkeiten, um die jeweiligen Geokoordinaten zu erfassen (EgiGeoZone mit Network oder Webservices Plugin) und die Fahrzeit zu berechnen (Traffic Plugin).<a class="moretag" href="https://www.smarthomeng.de/google-maps-widget-fuer-smartvisu-2-9"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<p>Auch in der Visualisierung kann es von Nutzen sein, seine aktuelle Position und ggf. eine Fahrtroute auf einer Google Maps Karte zu visualisieren. SmartHomeNG bietet eine Reihe an Plugins und Möglichkeiten, um die jeweiligen Geokoordinaten zu erfassen (EgiGeoZone mit Network oder Webservices Plugin) und die Fahrzeit zu berechnen (Traffic Plugin). Die Anzeige dieser Daten muss jedoch in der Visualisierung geschehen. <span id="more-1995"></span><br />
Aus dieser Motivation heraus habe ich ein Google Maps Widget für die SmartVISU geschrieben, welches mir meine aktuelle Position, meine Heimkoordinaten und den Weg zur Arbeit bzw. den Weg von der aktuellen Position nach Hause anzeigt.</p>
<p>In <a href="https://www.smarthomeng.de/geozonen-basierte-services-mit-der-egigeozone-app-und-dem-network-plugin" target="_blank" rel="noopener">https://www.smarthomeng.de/geozonen-basierte-services-mit-der-egigeozone-app-und-dem-network-plugin</a> wurde beschrieben, wie man Positionsdaten in SmartHomeNG übertragen kann. In <a href="https://www.smarthomeng.de/das-traffic-plugin-am-beispiel-eines-staualarms" target="_blank" rel="noopener">https://www.smarthomeng.de/das-traffic-plugin-am-beispiel-eines-staualarms</a> wurde beschrieben, wie das Traffic Plugin (Google Directions) in SmartHomeNG eingebunden werden kann. Items aus beiden Artikeln werden für das Plugin benötigt!</p>
<p><strong>Tipp:</strong> Am Ende des Artikels findet sich noch eine einfachere Version, die nur die aktuelle Position benötigt (und anzeigt)!</p>
<h1>Items</h1>
<p>Basis bilden ein Teil bzw. eine Erweiterung der Items aus dem EgiGeoZone und den Traffic Plugin Artikel. Bitte auf diese Artikel referenzieren, wie die Items belegt werden können.</p>
<pre><code class="language-yaml">
%YAML 1.1
---
location:

	home:
		lat:
			type: str
			value: 48.263530
			cache: 'yes'

		lon:
			type: str
			value: 11.443952
			cache: 'yes'
	
	work:

		lat:
			type: str
			value: 48.143158
			cache: 'yes'

		lon:
			type: str
			value: 11.547755
			cache: 'yes'
			
	lat:
		type: str
		cache: 'yes'

	lon:
		type: str
		cache: 'yes'

travel_info:
       
        calculate_way_home:
                type: bool
                cache: 'yes'

        calculate_way_work:
                type: bool
                cache: 'yes'

        travel_summary:
                type: str
 
</code></pre>
<p>Neben den jeweiligen GPS Koordinaten der aktuellen Position (<code>location.lat, location.lon</code>), der Home-Koordinate (<code>location.home.lat, location.home.lon</code>) und der Koordinate der Arbeitsstelle (<code>location.work.lat, location.work.lon</code>), sind hier auch zwei boolsche Items, die angeben, ob jeweils der Weg nach Hause oder in die Arbeit angezeigt werden soll (<code>travel_info.calculate_way_home</code> und <code>travel_info.calculate_way_work</code>) Für die Anzeige darf jeweils nur eines dieser Items <code>True</code> sein. Näheres ist in <a href="https://www.smarthomeng.de/das-traffic-plugin-am-beispiel-eines-staualarms" target="_blank" rel="noopener">https://www.smarthomeng.de/das-traffic-plugin-am-beispiel-eines-staualarms</a> beschrieben.</p>
<p><strong>Tipp:</strong> Man kann natürlich auch die &#8222;aktuelle&#8220; Koordinate <code>location.lat, location.lon</code> fest im Item hinterlegen, ohne dieses via EgiGeoZone zu bedaten. Diese Koordinate ist, so lange keine Route angezeigt wird, das Zentrum der Karte!</p>
<h1>Google Maps Widget</h1>
<p>Für das Widget sind im Ordner <code>dropins/widgets</code> zwei Dateien zu erstellen. Im Javascript File wird dabei die Karte initialisiert und falls angegeben, die Verkehrsanzeige eingeschaltet. Daneben wird ein Marker auf die Home Koordinate und die aktuelle Position gesetzt. Letzterer ist mit einem Foto hinterlegt.</p>
<p>Im Update-Block werden die jeweiligen Positionen aktualisiert und die aktuelle Route gesetzt (falls eine Route aktuell angezeigt werden soll).</p>
<p>Im JS-File muss bedacht werden, dass der im Rahmen des Traffic Plugins eingerichtete API Key für die Google Directions API angegeben werden muss (<code>&lt;apikey&gt</code>)! Zudem kann als Title noch der jeweilige Name <code>&lt;Mein Name&gt;</code> gesetzt werden.</p>
<p><strong><code>dropins/widgets/gmaps.js</code>:</strong></p>
<pre><code class="language-javascript">
// dropins/widgets/gmaps.js
$.widget("sv.gmaps_map", $.sv.widget, {
    initSelector: 'div[data-widget="gmaps_map"]',

    options: {
        'traffic': null,
    },

    _create: function () {
        this._super();
        this._create_map();
    },

    _create_map: function () {
        try {
            this.map = new google.maps.Map(this.element[0], {
                zoom: 11,
                disableDefaultUI: false,
                clickableIcons: false,
                mapTypeControl: false,
                streetViewControl: false
            });
        }
        catch(e) {
            if(e.name == "ReferenceError") { // google maps script not loaded yet
                var that = this;
                // google maps script is already loading in another widget
                if(window.google_maps_loading) { 
                    window.setTimeout(function() { that._create_map() }, 100)
                    return;
                }
                // google maps script is not loading
                window.google_maps_loading = true;
                $.ajax({
                    url: 'https://maps.googleapis.com/maps/api/js?key=&lt;apikey&gt;',
                    dataType: "script",
                    complete: function() { window.google_maps_loading = false; that._create_map() }
                });
                return;
            }
            else  // other exceptions should be trown
                throw e;
        }

        this.directionsService = new google.maps.DirectionsService;
        this.directionsDisplay = new google.maps.DirectionsRenderer();
        this.directionsDisplay.setMap(this.map);

        if (this.options['traffic']) {
            var trafficLayer = new google.maps.TrafficLayer();
            trafficLayer.setMap(this.map);
        }

        var pinColorGreen = "20d24a";
        var pinImageGreen = new google.maps.MarkerImage("https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|" + pinColorGreen,
            new google.maps.Size(21, 34),
            new google.maps.Point(0,0),
            new google.maps.Point(10, 34));
        var pinImageMyself = new google.maps.MarkerImage("/smartVISU/pics/phone/myself.jpg" ,
            null, null, null, new google.maps.Size(40, 40));
        var pinShadow = new google.maps.MarkerImage("https://chart.apis.google.com/chart?chst=d_map_pin_shadow",
            new google.maps.Size(40, 37),
            new google.maps.Point(0, 0),
            new google.maps.Point(12, 35));

        this.marker_home = new google.maps.Marker({
            map: this.map,
            icon: pinImageGreen,
            shadow: pinShadow,
            title:' Home '
        });

        this.marker_myself = new google.maps.Marker({
            map: this.map,
            icon: pinImageMyself,
            title:' &lt;Mein Name&gt;',
            zIndex:99999999
        });
    },

    _update: function(response) {

        if(!this.map) {
            var that = this;
            window.setTimeout(function() { that._update(response) }, 100)
            return;
        }

        this.map.setCenter({lat: response[0], lng: response[1]});
        var pos = new google.maps.LatLng(parseFloat(response[0]),parseFloat(response[1]));
        this.marker_myself.setPosition(pos);

        var pos_home = new google.maps.LatLng(parseFloat(response[2]),parseFloat(response[3]));
        this.marker_home.setPosition(pos_home);
        if (response[6] && response[7] && (response[4] == 1 || response[5] == 1)) {
            if (response[4] == 1) {
                var destination = { lat: parseFloat(response[2]), lng: parseFloat(response[3]) };
            } else if (response[5] == 1) {
                var destination = { lat: parseFloat(response[6]), lng: parseFloat(response[7]) };
            };
            var directionsDisplay = this.directionsDisplay;
            this.directionsDisplay.setMap(this.map);
            this.directionsService.route({
                origin: pos,
                //provideRouteAlternatives: true,
                destination: destination,
                travelMode: google.maps.TravelMode.DRIVING
            }, function(result, status) {
                if (status === google.maps.DirectionsStatus.OK) {
                    directionsDisplay.setDirections(result);
                } else {
                    console.log('Directions request failed due to ' + status);
                }
            });
        } else {
            if(this.directionsDisplay != null) {
                this.directionsDisplay.setMap(null);
            }
        }
    }
})
</code></pre>
<p>&nbsp;</p>
<p>und <strong><code>dropins/widgets/gmaps.html</code>:</strong></p>
<pre><code class="language-twig">
// dropins/widgets/gmaps.html - API Key für Google Directions angeben!
/**
 * Displays a google maps map with current, home and work position, as well as routing
 *
 * @param unique id for this widget
 * @param a gad/item for latitude
 * @param a gad/item for longitude
 * @param a gad/item for home latitude
 * @param a gad/item for home longitude
 * @param a gad/item for bool flag, if route to home shall be calculated
 * @param a gad/item for bool flag, if route to work shall be calculated
 * @param a gad/item for work latitude
 * @param a gad/item for work longitude
 * @param traffic information on (=1) or off (=0)
 */
{% macro map(id, gad_lat, gad_lon, gad_home_lat, gad_home_lon, gad_calculate_way_home, gad_calculate_way_work, gad_work_lat, gad_work_lon, traffic) %}
    &lt;div id="{{ uid(page, id) }}" style="width: 100%; height: 400px;" data-traffic="{{ traffic }}" data-widget="gmaps_map" data-item="{{ gad_lat }}, {{ gad_lon}}, {{ gad_home_lat }}, {{ gad_home_lon }}, {{ gad_calculate_way_home }}, {{ gad_calculate_way_work }}, {{ gad_work_lat }}, {{ gad_work_lon }}"&gt;&lt;/div&gt;
{% endmacro %}
</code></pre>
<p>Weiterhin wird ein Bild, welches unter <code>/smartVISU/pics/phone/myself.jpg</code> abgelegt ist, verwendet! Damit das Widget ordentlich funktioniert, sollte dieses Bild auch dort existieren.</p>
<h1>Einbindung in smartVISU 2.9</h1>
<p>Da die Widgets mit smartVISU 2.9 automatisch geladen werden, muss nun nur noch das Widget auf der entsprechenden Seite eingebunden werden:</p>
<pre><code class="language-twig">
&lt;div class="block" style="width: 100%;"&gt;
  &lt;div class="set-2" data-role="collapsible-set" data-theme="c" data-content-theme="a" data-mini="true"&gt;
    &lt;div data-role="collapsible" data-collapsed="false"&gt;
      &lt;h3&gt;Verkehr:
      {{ basic.symbol('travel_info.calculate_way_home', 'travel_info.calculate_way_home', 'Nach Hause via ', '', '1') }}
      {{ basic.symbol('travel_info.calculate_way_work', 'travel_info.calculate_way_work', 'Zur Arbeit via ', '', '1') }}
      {{ basic.print('travel_info.travel_summary', 'travel_info.travel_summary', 'text') }}
      &lt;/h3&gt;
      {{ gmaps.map('trafficmap', 'location.lat', 'location.lon', 'location.home.lat', 'location.home.lon', 'travel_info.calculate_way_home', 'travel_info.calculate_way_work', 'location.work.lat', 'location.work.lon', '1') }}
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;  
</code></pre>
<p>Das Ergebnis mit aktivem Arbeitsweg, sieht dann wie folgt aus:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/08/kartenansicht.jpg" alt="" width="830" height="472" class="alignnone size-full wp-image-2016" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/08/kartenansicht.jpg 830w, https://www.smarthomeng.de/wp-content/uploads/2018/08/kartenansicht-300x171.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2018/08/kartenansicht-768x437.jpg 768w" sizes="(max-width: 830px) 100vw, 830px" /></p>
<h1>Einfachere Version:</h1>
<p>Hier noch eine einfachere Version des Widgets, nur mit Koordinaten der aktuellen Position:</p>
<pre><code class="language-twig">
{{ gmaps.simple_map('trafficmap_simple', 'location.lat', 'location.lon') }}
</code></pre>
<pre><code class="language-twig">
/**
 * Displays a simple google maps map
 *
 * @param unique id for this widget
 * @param a gad/item for latitude
 * @param a gad/item for longitude
 */
{% macro simple_map(id, gad_lat, gad_lon) %}
&lt;div id="{{ uid(page, id) }}" style="width: 100%; height: 400px;" data-widget="gmaps_simplemap" data-item="{{ gad_lat }}, {{ gad_lon}}"&gt;&lt;/div&gt;
{% endmacro %}
</code></pre>
<pre><code class="language-javascript">
$.widget("sv.gmaps_simplemap", $.sv.widget, {
    initSelector: 'div[data-widget="gmaps_simplemap"]',

    _create: function () {
        this._super();
        this._create_map();
    },

    _create_map: function () {
        try {
            this.map = new google.maps.Map(this.element[0], {
                zoom: 11,
                disableDefaultUI: false,
                clickableIcons: false,
                mapTypeControl: false,
                streetViewControl: false
            });
        }
        catch (e) {
            if (e.name == "ReferenceError") { // google maps script not loaded yet
                var that = this;
                // google maps script is already loading in another widget
                if (window.google_maps_loading) {
                    window.setTimeout(function () {
                        that._create_map()
                    }, 100)
                    return;
                }
                // google maps script is not loading
                window.google_maps_loading = true;
                $.ajax({
                    url: 'https://maps.googleapis.com/maps/api/js?key=&lt;apikey&gt;',
                    dataType: "script",
                    complete: function () {
                        window.google_maps_loading = false;
                        that._create_map()
                    }
                });
                return;
            }
            else  // other exceptions should be thrown
                throw e;
        }

        var pinColorGreen = "20d24a";
        var pinImageGreen = new google.maps.MarkerImage("https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|" + pinColorGreen,
            new google.maps.Size(21, 34),
            new google.maps.Point(0,0),
            new google.maps.Point(10, 34));
        this.marker_myself = new google.maps.Marker({
            map: this.map,
            icon: pinImageGreen,
            title:' &lt;Mein Name&gt;',
            zIndex:99999999
        });
    },

    _update: function(response) {
        if(!this.map) {
            var that = this;
            window.setTimeout(function() { that._update(response) }, 100)
            return;
        }

        this.map.setCenter({lat: response[0], lng: response[1]});
        var pos = new google.maps.LatLng(parseFloat(response[0]),parseFloat(response[1]));
        this.marker_myself.setPosition(pos);
    }
});</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/google-maps-widget-fuer-smartvisu-2-9/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Fehlerbehandlung für Plugins bei nicht installierten Python Packages</title>
		<link>https://www.smarthomeng.de/fehlerbehandlung-fuer-plugins-bei-nicht-installierten-python-packages</link>
					<comments>https://www.smarthomeng.de/fehlerbehandlung-fuer-plugins-bei-nicht-installierten-python-packages#comments</comments>
		
		<dc:creator><![CDATA[Martin Sinn]]></dc:creator>
		<pubDate>Sun, 12 Aug 2018 08:54:08 +0000</pubDate>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Tipps & Tricks]]></category>
		<category><![CDATA[Entwicklung]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=1973</guid>

					<description><![CDATA[UPDATE: Im develop Branch (also für SmartHomeNG v1.6) ist eine allgemein gültige Lösung implementiert. (Danke an ohinckel für die Idee). Ab der Version muss der Fehler nicht mehr im einzelnen Plugin abgefangen werden, es sei denn, man möchte nicht das Laden des Plugins unterbinden, sondern vielleicht nur einzelne Funktionen des<a class="moretag" href="https://www.smarthomeng.de/fehlerbehandlung-fuer-plugins-bei-nicht-installierten-python-packages"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<p><strong>UPDATE</strong>:</p>
<p>Im develop Branch (also für SmartHomeNG v1.6) ist eine allgemein gültige Lösung implementiert. (Danke an ohinckel für die Idee).</p>
<p>Ab der Version muss der Fehler nicht mehr im einzelnen Plugin abgefangen werden, es sei denn, man möchte nicht das Laden des Plugins unterbinden, sondern vielleicht nur einzelne Funktionen des Plugins deaktivieren.</p>
<hr />
<p>&nbsp;</p>
<p>Wenn ein Plugin ein spezielles Python Package benötigt (Requirement) und dieses auf dem System des Anwenders nicht installiert ist, wird im Log beim ersten Zugriff auf Funktionen dieses Packages eine Exception in das Logfile geschrieben.</p>
<p>Für viele Anwender ist es schwierig, aus der Fehlermeldung auf die eigentliche Ursache zu schließen.</p>
<p>Durch einen kleinen Kniff im Plugin, kann im Logfile eine klare Fehlermeldung geschrieben werden. Außerdem kann das Laden des Plugins unterbunden werden, um Folgefehler zu vermeiden.</p>
<p>&nbsp;</p>
<h3>Vorgehen</h3>
<p>Die zwei notwendigen Änderungen sind hier Beispiel des <strong>homematic</strong> Plugins und des benötigten Packages <strong>pyhomematic</strong> beschrieben.</p>
<p>&nbsp;</p>
<p>Normalerweise wird das Package folgendermaßen importiert:</p>
<pre><code class="language-python">
from pyhomematic import HMConnection
</code></pre>
<p>Um den Fehler zu behandeln, werden folgende zwei Änderungen vorgenommen:</p>
<ol>
<li>Um den Fehler zu erkennen, wird die <strong>import</strong> Anweisung in ein <strong>try/except</strong> Konstrukt eingebettet und abhängig vom Ergebnis eine Variable gesetzt. (Zeilen 8 bis 12 im folgenden Beispiel)</li>
<li>Um den erkannten Fehler auszuwerten, wird eine <strong>If-Anweisung</strong> zur<strong>__init__</strong> Methode hinzugefügt (Zeilen 37 bis 41), die Im Fehlerfall einen sinnvollen Log-Eintrag schreibt und durch das setzen der Variable self._init_complete signaliseiert, dass das Plugin sich nicht fehlerfrei initialisieren konnte. Das anschließende <strong>return</strong> sorgt dann noch für den Abbruch der Initialisierung.</li>
</ol>
<p>&nbsp;</p>
<pre data-line="8-12,37-41"><code class="language-python">
#  You should have received a copy of the GNU General Public License
#  along with SmartHomeNG. If not, see &lt;http://www.gnu.org/licenses/&gt;.
#
#########################################################################

import logging

try:
    from pyhomematic import HMConnection
    REQUIRED_PACKAGE_IMPORTED = True
except:
    REQUIRED_PACKAGE_IMPORTED = False

from lib.module import Modules
from lib.model.smartplugin import *

from time import sleep


class Homematic(SmartPlugin):
    """
    Main class of the Plugin. Does all plugin specific stuff and provides
    the update functions for the items
    """
    
    PLUGIN_VERSION = '1.5.0'
    
    connected = False
    

    def __init__(self, sh, *args, **kwargs):
        """
        Initalizes the plugin. The parameters descriptions for this method are pulled from the entry in plugin.yaml.
        """
        self.logger = logging.getLogger(__name__)

        # Exit if the required package(s) could not be imported
        if not REQUIRED_PACKAGE_IMPORTED:
            self.logger.error("{}: Unable to import Python package 'pyhomematic'".format(self.get_fullname()))
            self._init_complete = False
            return

        # get the parameters for the plugin (as defined in metadata plugin.yaml):
        #   self.param1 = self.get_parameter_value('param1')


</code></pre>
<p>Im Logfile wird der Fehler dann durch zwei Zeilen, wie im folgenden Beispiel angezeigt:</p>
<pre><code class="language-batch">
2018-08-12  09:59:03 ERROR    plugins.homematic   homematic_hm1: Unable to import Python package 'pyhomematic'
2018-08-12  09:59:03 ERROR    lib.plugin          Plugins: Plugin 'homematic' initialization failed, plugin not loaded
</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/fehlerbehandlung-fuer-plugins-bei-nicht-installierten-python-packages/feed</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>E-Paper Wetterstation mit Daten aus SmartHomeNG</title>
		<link>https://www.smarthomeng.de/epaper-wetterstation-mit-daten-aus-smarthomeng</link>
					<comments>https://www.smarthomeng.de/epaper-wetterstation-mit-daten-aus-smarthomeng#comments</comments>
		
		<dc:creator><![CDATA[Marc René Frieß]]></dc:creator>
		<pubDate>Sun, 22 Jul 2018 09:28:47 +0000</pubDate>
				<category><![CDATA[Beispiel-Implementierungen]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Arduino IDE]]></category>
		<category><![CDATA[EPaper]]></category>
		<category><![CDATA[ESP32]]></category>
		<category><![CDATA[Waveshare]]></category>
		<category><![CDATA[Wetterstation]]></category>
		<guid isPermaLink="false">https://www.smarthomeng.de/?p=1929</guid>

					<description><![CDATA[E-Paper Displays, wie sie etwa im Amazon Kindle zum Einsatz kommen, stellen eine hervoragende und energiesparende Möglichkeit dar, Daten von SmartHomeNG zu visualisieren. Im folgenden Artikel soll als Beispiel eine Wetterstation auf Basis eines ESP32 und eines Waveshare 4.2 Zoll E-Paper Display mit 400 x 300 Pixel Auflösung erstellt werden.<a class="moretag" href="https://www.smarthomeng.de/epaper-wetterstation-mit-daten-aus-smarthomeng"> Weiterlesen&#8230;</a>]]></description>
										<content:encoded><![CDATA[<p>E-Paper Displays, wie sie etwa im Amazon Kindle zum Einsatz kommen, stellen eine hervoragende und energiesparende Möglichkeit dar, Daten von SmartHomeNG zu visualisieren.</p>
<p>Im folgenden Artikel soll als Beispiel eine Wetterstation auf Basis eines ESP32 und eines Waveshare 4.2 Zoll E-Paper Display mit 400 x 300 Pixel Auflösung erstellt werden.</p>
<p>Das Display kann bspw. via <a href="https://www.amazon.de/Module-Resolution-Electronic-Controller-Communicating/dp/B074NR1SW2" target="_blank" rel="noopener">Amazon</a> bezogen werden. Der verwendete ESP32 kann <a href="https://www.amazon.de/Espressif-ESP32-DEVKITC-Genuine-ESP-WROOM-32-Marked/dp/B07DZP27TH/ref=sr_1_5?s=computers&amp;ie=UTF8&amp;qid=1532247493&amp;sr=1-5&amp;keywords=espressif+esp32" target="_blank" rel="noopener">hier</a> gefunden werden. Als Bibliothek zum Rendern des Bildes kommt <a href="https://github.com/ZinggJM/GxEPD2" target="_blank" rel="noopener">GxEPD2</a> zum Einsatz.  Vorab muss allerdings gesagt werden, dass die Fonts der Bibliothek nur Standard ASCII Zeichen könne, also weder ein Grad Zeichen (°) noch deutsche Sonderzeichen. Als Icons wurden Teile aus <a href="http://adamwhitcroft.com/climacons/" target="_blank" rel="noopener">http://adamwhitcroft.com/climacons/</a> und den SmartVISU Icons verwendet, die via <a href="http://www.digole.com/tools/PicturetoC_Hex_converter.php" target="_blank" rel="noopener">http://www.digole.com/tools/PicturetoC_Hex_converter.php</a> von einem PNG in C-Arrays konvertiert wurden.</p>
<p>Der Artikel erhebt keinen Anspruch auf vollständige Korrektheit und Schönheit des C Codes und dient lediglich als Proof of Concept. Auch sind die Icons derzeit noch nicht vollständig. Der Artikel wird dazu sukzessive aktualisiert.</p>
<p>Für die Items wurden sowohl Systemdaten aus SHNG direkt, dem KNX Plugin, dem ETA PU Plugin, dem SMA EM, als auch des DarkSky Plugins verwendet, die via Webservices Plugin (siehe Tutorial <a href="https://www.smarthomeng.de/das-smarthomeng-webservices-plugin" target="_blank" rel="noopener">https://www.smarthomeng.de/das-smarthomeng-webservices-plugin</a>) verfügbar gemacht wurden. Teilweise wurden die Rohdaten der Plugins über Child-Items noch formatiert oder in Strings (bspw. beim UV Wert) umgerechnet.</p>
<h1>Verkabelung</h1>
<p>Dem Display ist ein Kabel beigelegt, das wie folgt an den ESP32 angeschlossen wird:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/07/Kabel_Waveshare.jpg" alt="" width="733" height="638" class="alignnone size-full wp-image-1935" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/07/Kabel_Waveshare.jpg 733w, https://www.smarthomeng.de/wp-content/uploads/2018/07/Kabel_Waveshare-300x261.jpg 300w" sizes="(max-width: 733px) 100vw, 733px" /></p>
<table border="1" style="border-collapse: collapse; width: 100%;">
<tbody>
<tr style="height: 29px;">
<td style="width: 50%; height: 29px;"><strong>Farbe</strong></td>
<td style="width: 50%; height: 29px;"><strong>Anschluß</strong></td>
</tr>
<tr style="height: 29px;">
<td style="width: 50%; height: 29px;"><strong><span style="color: #ff0000;">rot</span></strong></td>
<td style="width: 50%; height: 29px;">3v3</td>
</tr>
<tr style="height: 29px;">
<td style="width: 50%; height: 29px;"><strong>schwarz</strong></td>
<td style="width: 50%; height: 29px;">GND</td>
</tr>
<tr style="height: 29px;">
<td style="width: 50%; height: 29px;"><strong><span style="color: #0000ff;">blau</span></strong></td>
<td style="width: 50%; height: 29px;">IO23</td>
</tr>
<tr style="height: 29px;">
<td style="width: 50%; height: 29px;"><span style="color: #e3eb15;"><strong>gelb</strong></span></td>
<td style="width: 50%; height: 29px;">IO18</td>
</tr>
<tr style="height: 29px;">
<td style="width: 50%; height: 29px;"><span style="color: #ff9900;"><strong>orange</strong></span></td>
<td style="width: 50%; height: 29px;">IO17</td>
</tr>
<tr style="height: 29px;">
<td style="width: 50%; height: 29px;"><span style="color: #339966;"><strong>grün</strong></span></td>
<td style="width: 50%; height: 29px;">IO16</td>
</tr>
<tr style="height: 29px;">
<td style="width: 50%; height: 29px;"><span style="color: #d6d6d6;"><strong>weiß</strong></span></td>
<td style="width: 50%; height: 29px;">IO5</td>
</tr>
<tr style="height: 29px;">
<td style="width: 50%; height: 29px;"><span style="color: #800080;"><strong>lila</strong></span></td>
<td style="width: 50%; height: 29px;">IO19</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h1>Items (via Webservices Plugin)</h1>
<p>Folgende Items werden als Itemset vom Webservices Plugin als JSON bereitgestellt:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/07/epaper_json.jpg" alt="" width="685" height="786" class="alignnone size-full wp-image-1936" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/07/epaper_json.jpg 685w, https://www.smarthomeng.de/wp-content/uploads/2018/07/epaper_json-261x300.jpg 261w" sizes="(max-width: 685px) 100vw, 685px" /></p>
<h1>Code</h1>
<p>Das Programm wurde mit der Arduino IDE geschrieben und auf den ESP32 übertragen. Wie oben bereits erwähnt, müssen dazu die notwendigen Bibliotheken vorhanden sein. Wie der ESP32 in der Arduino IDE eingerichtet werden kann, kann <a href="https://www.smarthomeng.de/entfernungsmessung-auf-basis-eines-esp32-und-smarthomeng" target="_blank" rel="noopener">https://www.smarthomeng.de/entfernungsmessung-auf-basis-eines-esp32-und-smarthomeng</a> entnommen werden.</p>
<p>In der Methode <code>void setup(void)</code> werden zunächst das Display und die WLAN Verbindung initialisiert.<br />
In <code>void loop()</code> findet dann der Datenzugriff und das Rendering statt. Nach erfolgreicher Verbindung zu SmartHomeNG wird zuerst der HTTP Header herausgefiltert. Sobald in der Response eine geschweifte Klammer erkannt wird, werden die JSON Daten in ein Char Array (<code>inData</code>) eingelesen. Ist dies vollendet, wird die Verbindung getrennt und der JSON Datensatz geparsed (<code>JsonObject&amp; root = jsonBuffer.parseObject(inData);</code>). Bei Erfolg, werden die Daten mit <code>printJsonData(JsonObject&amp; root)</code> auf dem Display ausgegeben. Dafür werden sie aus den JSON Daten extrahiert und ggf. noch formatiert.</p>
<p>Im &#8222;do &#8230; while&#8220; Block findet die konkrete Ausgabe statt. <code>display.setCursor</code> setzt den Textcursor an bestimmte Positionen. Danach wird Text ausgegeben. Die Methode <code>void display_icon(int x, int y, String icon_name)</code> gibt an entsprechenden Positionen das Icon aus.<br />
Die Methoden <code>void dashedRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)</code> und <code>void drawDashedHLine(int16_t x, int16_t y, int16_t w, uint16_t color)</code> wurden von <a href="https://forum.arduino.cc/index.php?topic=487007.225" target="_blank" rel="noopener">https://forum.arduino.cc/index.php?topic=487007.225</a> übernommen und zeichnen Linien oder Rechtecke.</p>
<pre><code class="language-c">
#include &lt;WiFi.h&gt;
#include &lt;WiFiServer.h&gt;
#include &lt;WiFiClient.h&gt;
#include &lt;WiFiUdp.h&gt;
#include &lt;JsonParser.h&gt;
#include &lt;ArduinoJson.h&gt;
#include &lt;GxEPD2_BW.h&gt;
#include &lt;GxEPD2_3C.h&gt;
#define EPD_CS 17 //SS
#include &lt;Fonts/FreeMonoBold9pt7b.h&gt;
#include &lt;Fonts/FreeMonoBold12pt7b.h&gt;
#include &lt;Fonts/FreeMonoBold18pt7b.h&gt;

// Define each of the *icons for display
const unsigned char gate_open[] PROGMEM = {
0x00,0x00,0x1f,0xff,0xff,0xe0,0x00,0x00,0x00,0x3f,0xff,0xff,0xf0,0x00,0x00,0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x00,0x70,0x00,0x00,0x38,0x00
,0x00,0x00,0x60,0x00,0x00,0x18,0x00,0x00,0x00,0x60,0x00,0x00,0x18,0x00,0x00,0x00,0xe0,0x00,0x00,0x1c,0x00,0x00,0x00,0xe0,0x00,0x00,0x1c,0x00
,0x00,0x00,0xe0,0x00,0x00,0x1c,0x00,0x00,0x00,0xff,0xff,0xff,0xfc,0x00,0x00,0x03,0xff,0xff,0xff,0xfe,0x00,0x00,0x03,0x03,0xc0,0x0f,0x03,0x00
,0x00,0x02,0x03,0xff,0xff,0x01,0x00,0x00,0x02,0x03,0xff,0xff,0x01,0x00,0x00,0x03,0x07,0x80,0x07,0x83,0x00,0x00,0x03,0xff,0xff,0xff,0xff,0x00
,0x00,0x03,0xff,0xff,0xff,0xff,0x00,0x00,0x03,0xff,0xff,0xff,0xff,0x00,0x00,0x01,0xff,0xff,0xff,0xfe,0x00,0x00,0x01,0xf8,0x00,0x00,0x7c,0x00
,0x00,0x01,0xf8,0x00,0x00,0x7c,0x00,0x00,0x01,0xf8,0x00,0x00,0x7c,0x00,0x00,0x00,0xf0,0x00,0x00,0x7c,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00
,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xf8,0x00,0x00,0x00,0x00,0x80,0xff,0xf8,0x00,0x00,0x00,0x00,0xc0
,0xff,0x38,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0
,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0
,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0
,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0
,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xdf,0x18,0x00,0x00,0x00,0x00,0xc0,0xff,0xf8,0x00,0x00,0x00,0x00,0xc0,0xff,0xf8,0x00,0x00,0x00,0x00,0xc0
,0xff,0xf8,0x00,0x00,0x00,0x00,0xc0,0x1f,0xff,0xff,0xff,0xff,0xff,0xc0
};

const unsigned char gate_closed[] PROGMEM = {
0x00,0x00,0xff,0xff,0xff,0x00,0x00,0x01,0xff,0xff,0xff,0x80,0x00,0x03,0x80,0x00,0x01,0xc0,0x00,0x03,0x80,0x00,0x01,0xc0
,0x00,0x03,0x00,0x00,0x00,0xc0,0x00,0x03,0x00,0x00,0x00,0xc0,0x00,0x07,0x00,0x00,0x00,0xe0,0x00,0x07,0x00,0x00,0x00,0xe0
,0x00,0x07,0x00,0x00,0x00,0xe0,0x00,0x07,0xff,0xff,0xff,0xe0,0x00,0x0f,0xff,0xff,0xff,0xf0,0x00,0x18,0x1e,0x00,0x78,0x18
,0x00,0x10,0x1f,0xff,0xf8,0x08,0x00,0x10,0x1f,0xff,0xf8,0x08,0x00,0x18,0x3c,0x00,0x3c,0x18,0x00,0x1f,0xff,0xff,0xff,0xf8
,0x00,0x1f,0xff,0xff,0xff,0xf8,0x00,0x1f,0xff,0xff,0xff,0xf8,0x00,0x0f,0xff,0xff,0xff,0xf0,0x00,0x0f,0xc0,0x00,0x03,0xe0
,0x00,0x0f,0xc0,0x00,0x03,0xe0,0x00,0x0f,0xc0,0x00,0x03,0xe0,0x00,0x07,0x80,0x00,0x03,0xe0,0x60,0x00,0x00,0x00,0x00,0x00
,0xe0,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xe7,0xff,0xff,0xff,0xff,0xf4,0xef,0xff,0xff,0xff,0xff,0xf6
,0xee,0x71,0xce,0x71,0xce,0x76,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36
,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36
,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36
,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36
,0xec,0x31,0x8e,0x31,0x8e,0x36,0xec,0x31,0x8e,0x31,0x8e,0x36,0xef,0xff,0xff,0xff,0xff,0xf6,0xef,0xff,0xff,0xff,0xff,0xf6
,0xe7,0xff,0xff,0xff,0xff,0xf6,0x7f,0xff,0xff,0xff,0xff,0xfe
};

const unsigned char light_off[] PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x00,0x00,0x00
,0x00,0x00,0x7e,0x1f,0x80,0x00,0x00,0x00,0x00,0xf0,0x03,0xc0,0x00,0x00,0x00,0x01,0xe0,0x01,0xe0,0x00,0x00,0x00,0x03,0xc0,0x00,0xf0,0x00,0x00
,0x00,0x03,0x80,0x00,0x70,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00
,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00
,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x03,0x80,0x00,0x70,0x00,0x00,0x00,0x03,0x80,0x00,0x70,0x00,0x00
,0x00,0x01,0xc0,0x00,0xe0,0x00,0x00,0x00,0x01,0xc0,0x00,0xe0,0x00,0x00,0x00,0x00,0xe0,0x01,0xc0,0x00,0x00,0x00,0x00,0xf0,0x03,0xc0,0x00,0x00
,0x00,0x00,0x70,0x03,0x80,0x00,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00
,0x00,0x00,0x1c,0x0e,0x00,0x00,0x00,0x00,0x00,0x1c,0x0e,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xf0,0x00,0x00,0x00
,0x00,0x00,0x03,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00
};

const unsigned char light_on[] PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x03,0x00,0xe0,0x30,0x00,0x00
,0x00,0x03,0x80,0xe0,0x70,0x00,0x00,0x00,0x03,0x80,0xe0,0x70,0x00,0x00,0x00,0x01,0xc0,0x00,0xe0,0x00,0x00,0x00,0x01,0xc0,0x00,0xe0,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x20,0x00,0x03,0xc0,0x0f,0xfc,0x00,0xf0,0x00,0x03,0xe0,0x3f,0xff,0x01,0xf0,0x00
,0x01,0xf0,0xff,0x3f,0xc3,0xe0,0x00,0x00,0x61,0xf0,0x03,0xe1,0x80,0x00,0x00,0x01,0xe0,0x01,0xe0,0x00,0x00,0x00,0x03,0xc0,0x00,0xf0,0x00,0x00
,0x00,0x03,0x80,0x00,0x70,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x08,0x87,0x00,0x00,0x38,0x44,0x00
,0x1f,0x87,0x00,0x00,0x38,0x7e,0x00,0x1f,0x87,0x00,0x00,0x38,0x7e,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00
,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x07,0x00,0x00,0x38,0x00,0x00,0x00,0x03,0x80,0x00,0x70,0x00,0x00,0x00,0x03,0x80,0x00,0x70,0x00,0x00
,0x00,0xe1,0xc0,0x00,0xe1,0x80,0x00,0x03,0xe1,0xe0,0x01,0xe1,0xf0,0x00,0x07,0xe0,0xe0,0x01,0xc1,0xf8,0x00,0x03,0x80,0xf0,0x03,0xc0,0x70,0x00
,0x00,0x00,0x70,0x03,0x80,0x00,0x00,0x00,0x00,0x78,0x07,0x80,0x00,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00
,0x00,0x00,0x1c,0x0e,0x00,0x00,0x00,0x00,0x00,0x1c,0x0e,0x00,0x00,0x00,0x00,0x00,0x18,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xf0,0x00,0x00,0x00
,0x00,0x00,0x03,0xf0,0x00,0x00,0x00,0x00,0x00,0x01,0xc0,0x00,0x00,0x00
};

const unsigned char moon_0_8[] PROGMEM = {
0x00,0x3c,0x00,0x01,0xff,0x80,0x07,0xff,0xe0,0x0f,0xff,0xf0,0x1f,0xff,0xf8,0x3f,0xff,0xfc,0x3f,0xff,0xfc,0x7f,0xff,0xfe
,0x7f,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xfe
,0x7f,0xff,0xfe,0x3f,0xff,0xfc,0x3f,0xff,0xfc,0x1f,0xff,0xf8,0x0f,0xff,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00
};

const unsigned char moon_1[] PROGMEM = {
0x00,0x3c,0x00,0x01,0xff,0x80,0x07,0xff,0xe0,0x0f,0xff,0xf0,0x1f,0xe1,0xf8,0x3f,0xf0,0x7c,0x3f,0xfc,0x3c,0x7f,0xfc,0x1e
,0x7f,0xfe,0x1e,0xff,0xfe,0x0f,0xff,0xff,0x0f,0xff,0xff,0x0f,0xff,0xff,0x0f,0xff,0xff,0x0f,0xff,0xfe,0x0f,0x7f,0xfe,0x1e
,0x7f,0xfc,0x1e,0x3f,0xfc,0x3c,0x3f,0xf0,0x7c,0x1f,0xe1,0xf8,0x0f,0xff,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00
};

const unsigned char moon_2[] PROGMEM = {
0x00,0x3c,0x00,0x01,0xff,0x80,0x07,0xff,0xe0,0x0f,0xff,0xf0,0x1f,0xe1,0xf8,0x3f,0xf0,0x7c,0x3f,0xfc,0x3c,0x7f,0xfc,0x1e
,0x7f,0xfe,0x1e,0xff,0xfe,0x0f,0xff,0xff,0x0f,0xff,0xff,0x0f,0xff,0xff,0x0f,0xff,0xff,0x0f,0xff,0xfe,0x0f,0x7f,0xfe,0x1e
,0x7f,0xfc,0x1e,0x3f,0xfc,0x3c,0x3f,0xf0,0x7c,0x1f,0xe1,0xf8,0x0f,0xff,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00
};

const unsigned char moon_3[] PROGMEM = {
0x00,0x3c,0x00,0x01,0xff,0x80,0x07,0xff,0xe0,0x0f,0xff,0xf0,0x1f,0xf1,0xf8,0x3f,0xf0,0x7c,0x3f,0xf0,0x3c,0x7f,0xf0,0x1e
,0x7f,0xf0,0x1e,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0x7f,0xf0,0x1e
,0x7f,0xf0,0x1e,0x3f,0xf0,0x3c,0x3f,0xf0,0x7c,0x1f,0xf1,0xf8,0x0f,0xff,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00
};

const unsigned char moon_4[] PROGMEM = {
0x00,0x3c,0x00,0x01,0xff,0x80,0x07,0xff,0xe0,0x0f,0xff,0xf0,0x1f,0xc1,0xf8,0x3f,0xc0,0x7c,0x3f,0x80,0x3c,0x7f,0x00,0x1e
,0x7f,0x00,0x1e,0xff,0x00,0x0f,0xff,0x00,0x0f,0xff,0x00,0x0f,0xff,0x00,0x0f,0xff,0x00,0x0f,0xff,0x00,0x0f,0x7f,0x00,0x1e
,0x7f,0x00,0x1e,0x3f,0x80,0x3c,0x3f,0xc0,0x7c,0x1f,0xc1,0xf8,0x0f,0xff,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00
};

const unsigned char moon_5[] PROGMEM = {
0x00,0x3c,0x00,0x01,0xff,0x80,0x07,0xff,0xe0,0x0f,0xff,0xf0,0x1f,0x81,0xf8,0x3e,0x00,0x7c,0x3c,0x00,0x3c,0x78,0x00,0x1e
,0x78,0x00,0x1e,0xf0,0x00,0x0f,0xf0,0x00,0x0f,0xf0,0x00,0x0f,0xf0,0x00,0x0f,0xf0,0x00,0x0f,0xf0,0x00,0x0f,0x78,0x00,0x1e
,0x78,0x00,0x1e,0x3c,0x00,0x3c,0x3e,0x00,0x7c,0x1f,0x81,0xf8,0x0f,0xff,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00
};

const unsigned char moon_6[] PROGMEM = {
0x00,0x3c,0x00,0x01,0xff,0x80,0x07,0xff,0xe0,0x0f,0xff,0xf0,0x1f,0x8f,0xf8,0x3e,0x0f,0xfc,0x3c,0x0f,0xfc,0x78,0x0f,0xfe
,0x78,0x0f,0xfe,0xf0,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0xff,0x78,0x0f,0xfe
,0x78,0x0f,0xfe,0x3c,0x0f,0xfc,0x3e,0x0f,0xfc,0x1f,0x8f,0xf8,0x0f,0xff,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00
};

const unsigned char moon_7[] PROGMEM = {
0x00,0x3c,0x00,0x01,0xff,0x80,0x07,0xff,0xe0,0x0f,0xff,0xf0,0x1f,0x87,0xf8,0x3e,0x0f,0xfc,0x3c,0x3f,0xfc,0x78,0x3f,0xfe
,0x78,0x7f,0xfe,0xf0,0x7f,0xff,0xf0,0xff,0xff,0xf0,0xff,0xff,0xf0,0xff,0xff,0xf0,0xff,0xff,0xf0,0x7f,0xff,0x78,0x7f,0xfe
,0x78,0x3f,0xfe,0x3c,0x3f,0xfc,0x3e,0x0f,0xfc,0x1f,0x87,0xf8,0x0f,0xff,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00
};

const unsigned char moon_8[] PROGMEM = {
0x00,0x3c,0x00,0x01,0xff,0x80,0x07,0xff,0xe0,0x0f,0xff,0xf0,0x1f,0x87,0xf8,0x3e,0x0f,0xfc,0x3c,0x3f,0xfc,0x78,0x3f,0xfe
,0x78,0x7f,0xfe,0xf0,0x7f,0xff,0xf0,0xff,0xff,0xf0,0xff,0xff,0xf0,0xff,0xff,0xf0,0xff,0xff,0xf0,0x7f,0xff,0x78,0x7f,0xfe
,0x78,0x3f,0xfe,0x3c,0x3f,0xfc,0x3e,0x0f,0xfc,0x1f,0x87,0xf8,0x0f,0xff,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00
};

const unsigned char pressure[] PROGMEM = {
0x00, 0x00, 0x84, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x84, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x4c, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x88, 0x88, 0x80, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x40, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x11, 0x08, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x80, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x04, 0x18, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x00
, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x18, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x00, 0x01, 0x80
, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x80, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x61, 0x80, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x80, 0x00, 0x03, 0xc0
, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x80
, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00
, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00
, 0x00, 0x08, 0x00, 0x00, 0x03, 0x80, 0x3f, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x80, 0x3f, 0xe0, 0x00
, 0x00, 0x20, 0x00, 0x00, 0x03, 0x80, 0x30, 0xe0, 0x00, 0x3c, 0xc0, 0x00, 0x00, 0x03, 0xfc, 0x30, 0xe7, 0xf0
, 0xff, 0x80, 0x00, 0x00, 0x03, 0xfc, 0x30, 0xe3, 0xf0, 0xe3, 0x80, 0x00, 0x00, 0x03, 0x8e, 0x3b, 0xe0, 0x38
, 0x01, 0x80, 0x00, 0x00, 0x03, 0x8e, 0x3f, 0xc1, 0xf8, 0x01, 0x80, 0x00, 0x00, 0x03, 0x8e, 0x3f, 0x07, 0xf8
, 0x01, 0x80, 0x00, 0x00, 0x03, 0x8e, 0x30, 0x0e, 0x38, 0x01, 0x80, 0x00, 0x00, 0x03, 0x8e, 0x30, 0x0e, 0x38
, 0x03, 0x80, 0x00, 0x00, 0x03, 0x8e, 0x30, 0x07, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x01, 0x8e, 0x30, 0x03, 0xf0
};

const unsigned char sunrise_sunset[] PROGMEM = {
0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x03,0xc0,0x00,0x00,0x00,0x00,0x03,0xc0,0x00,0x00,0x00,0x00,0x03,0xc0,0x00,0x00
,0x00,0x00,0x03,0xc0,0x00,0x00,0x00,0x00,0x03,0xc0,0x00,0x00,0x00,0x00,0x03,0xc0,0x00,0x00,0x01,0xc0,0x01,0x80,0x03,0x80
,0x01,0xe0,0x00,0x00,0x07,0x80,0x01,0xf0,0x00,0x00,0x0f,0x80,0x00,0xf8,0x00,0x00,0x1f,0x00,0x00,0x78,0x00,0x00,0x1e,0x00
,0x00,0x38,0x03,0xc0,0x1c,0x00,0x00,0x00,0x1f,0xf8,0x00,0x00,0x00,0x00,0x7f,0xfe,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00
,0x00,0x01,0xf8,0x1f,0x80,0x00,0x00,0x03,0xe0,0x07,0xc0,0x00,0x00,0x03,0xc0,0x03,0xc0,0x00,0x00,0x07,0x80,0x01,0xe0,0x00
,0x00,0x07,0x80,0x01,0xe0,0x00,0x00,0x0f,0x00,0x00,0xf0,0x00,0x7e,0x0f,0x00,0x00,0xf0,0x7e,0xff,0x0f,0x00,0x00,0xf0,0xff
,0xff,0x0f,0x00,0x00,0xf0,0xff,0x7e,0x0f,0x00,0x00,0xf0,0x7e,0x00,0x07,0x00,0x00,0xe0,0x00,0x00,0x07,0x80,0x01,0xe0,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x07,0xff,0xff,0xe0,0x00,0x00,0x0f,0xff,0xff,0xf0,0x00,0x00,0x0f,0xff,0xff,0xf0,0x00,0x00,0x07,0xff,0xff,0xe0,0x00
};

const unsigned char clear_day[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00
, 0x00, 0x38, 0x00, 0x30, 0x00, 0x70, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf0, 0x00
, 0x00, 0x3e, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x03, 0xe0, 0x00
, 0x00, 0x0f, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x07, 0x00, 0x78, 0x03, 0x80, 0x00
, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 0x00
, 0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x03, 0xf0, 0x00, 0x00
, 0x00, 0x00, 0x7c, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x78, 0x00, 0x00
, 0x00, 0x00, 0xf0, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x3c, 0x00, 0x00
, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x0f, 0xc1, 0xe0, 0x00, 0x1e, 0x0f, 0xc0
, 0x1f, 0xe1, 0xe0, 0x00, 0x1e, 0x1f, 0xe0, 0x1f, 0xe1, 0xe0, 0x00, 0x1e, 0x1f, 0xe0
, 0x0f, 0xc1, 0xe0, 0x00, 0x1e, 0x0f, 0xc0, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00
, 0x00, 0x00, 0xf0, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x3c, 0x00, 0x00
, 0x00, 0x00, 0x78, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0xf8, 0x00, 0x00
, 0x00, 0x00, 0x3f, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00
, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00
, 0x00, 0x07, 0x00, 0x78, 0x03, 0x80, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x03, 0xc0, 0x00
, 0x00, 0x1f, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0xf0, 0x00
, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x30, 0x00, 0x70, 0x00
, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const unsigned char temperature[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xcf, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0xb7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xb7, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0xb7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xb7, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0xb7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xb7, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0xb7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xb7, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x07, 0xb7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xb7, 0xc0, 0x00, 0x00
, 0x00, 0x00, 0x0f, 0x33, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x79, 0xe0, 0x00, 0x00
, 0x00, 0x00, 0x1e, 0xfd, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xfd, 0xe0, 0x00, 0x00
, 0x00, 0x00, 0x1e, 0x79, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x33, 0xc0, 0x00, 0x00
, 0x00, 0x00, 0x0f, 0x87, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const unsigned char prob_rain[] PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x07,0xff,0xc0,0x00,0x00
,0x00,0x00,0x3f,0xff,0xf0,0x00,0x00,0x00,0x00,0x7f,0xff,0xfc,0x00,0x00,0x00,0x01,0xff,0xff,0xfe,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0x00,0x00
,0x00,0x07,0xff,0xff,0xff,0x80,0x00,0x00,0x07,0xff,0xff,0xff,0xc0,0x00,0x00,0x0f,0xff,0xff,0xff,0xe0,0x00,0x00,0x0f,0xff,0xff,0xff,0xe0,0x00
,0x00,0x00,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00
,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00
,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x00,0x00,0x00,0x00,0x00,0x38,0xe0,0x00,0x00,0x00,0x00,0x00,0x38,0xe0,0x00,0x00
,0x00,0x00,0x00,0x1f,0xc0,0x00,0x00,0x00,0x00,0x00,0x1f,0x80,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

const unsigned char barometer[] PROGMEM = {
0x00,0x1f,0xe0,0x00,0x00,0x7f,0xf8,0x00,0x01,0xff,0xfe,0x00,0x03,0xf0,0x3f,0x00,0x0f,0x80,0x07,0xc0,0x0f,0x00,0x03,0xc0,0x1e,0x00,0x01,0xe0,0x3c,0x00,0x00,0xf0
,0x38,0x00,0x3c,0x70,0x70,0x00,0x3c,0x38,0x70,0x00,0x7c,0x38,0xf0,0x00,0xfc,0x3c,0xe0,0x07,0xf0,0x1c,0xe0,0x0f,0xe0,0x1c,0xe0,0x0f,0xc0,0x1c,0xe0,0x0f,0xc0,0x1c
,0xe0,0x1f,0x80,0x1c,0xe0,0x3f,0x80,0x1c,0xf3,0xfc,0x00,0x3c,0x71,0xf8,0x00,0x38,0x70,0xf0,0x00,0x38,0x38,0x70,0x00,0x70,0x3c,0x30,0x00,0xf0,0x1e,0x10,0x01,0xe0
,0x0f,0x00,0x03,0xc0,0x0f,0x80,0x07,0xc0,0x03,0xf0,0x3f,0x00,0x01,0xff,0xfe,0x00,0x00,0x7f,0xf8,0x00,0x00,0x1f,0xe0,0x00
};

const unsigned char wind_speed[] PROGMEM = {
0x00,0x00,0x00,0x00,0x01,0xfc,0x00,0x00,0x03,0x3f,0xf0,0x00,0x85,0x3e,0x1f,0x80,0xd9,0x3e,0x1f,0x38,0xf1,0x3e,0x0f,0x0c,0xc1,0x3e,0x0f,0x0c,0xc1,0x3e,0x0f,0x0c
,0xf1,0x3e,0x0f,0x0c,0xd9,0x3e,0x0f,0x18,0xc5,0x3e,0x1f,0xc0,0xc3,0x3f,0xf0,0x00,0xc1,0xfe,0x00,0x00,0xc0,0x80,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00
,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00
,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

const unsigned char rain[] PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00
,0x00,0x01,0xff,0xe0,0x00,0x00,0x00,0x00,0x07,0xff,0xf8,0x00,0x00,0x00,0x00,0x0f,0xff,0xfc,0x00,0x00,0x00,0x00,0x3f,0x80,0x7f,0x00,0x00,0x00
,0x00,0x7e,0x00,0x1f,0x80,0x00,0x00,0x00,0x78,0x00,0x07,0x80,0x00,0x00,0x00,0xf0,0x00,0x03,0xc0,0x00,0x00,0x01,0xe0,0x00,0x01,0xec,0x00,0x00
,0x01,0xe0,0x00,0x01,0xff,0xc0,0x00,0x03,0xc0,0x00,0x00,0xff,0xf0,0x00,0x03,0xc0,0x00,0x00,0xff,0xf8,0x00,0x03,0x80,0x00,0x00,0x40,0x7c,0x00
,0x03,0x80,0x00,0x00,0x00,0x3e,0x00,0x07,0x80,0x00,0x00,0x00,0x1e,0x00,0x07,0x80,0x00,0x00,0x00,0x0f,0x00,0x07,0x80,0x00,0x00,0x00,0x07,0x00
,0x07,0x80,0x00,0x00,0x00,0x07,0x00,0x03,0x80,0x00,0x00,0x00,0x07,0x80,0x03,0x80,0x00,0x00,0x00,0x07,0x80,0x03,0xc0,0x00,0x00,0x00,0x07,0x80
,0x03,0xc0,0x78,0x00,0x78,0x07,0x80,0x01,0xe0,0x78,0x00,0x78,0x07,0x00,0x01,0xe0,0x78,0x00,0x78,0x0f,0x00,0x00,0xf0,0x78,0x00,0x78,0x0f,0x00
,0x00,0x78,0x78,0x78,0x78,0x1e,0x00,0x00,0x78,0x78,0x78,0x78,0x3e,0x00,0x00,0x38,0x30,0x78,0x30,0x7c,0x00,0x00,0x08,0x00,0x78,0x00,0x78,0x00
,0x00,0x00,0x00,0x78,0x00,0x70,0x00,0x00,0x00,0x00,0x78,0x00,0x40,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x78,0x00,0x78,0x00,0x00,0x00,0x00,0x78,0x00,0x78,0x00,0x00,0x00,0x00,0x78,0x00,0x78,0x00,0x00,0x00,0x00,0x78,0x00,0x78,0x00,0x00
,0x00,0x00,0x78,0x78,0x78,0x00,0x00,0x00,0x00,0x78,0x78,0x78,0x00,0x00,0x00,0x00,0x30,0x78,0x30,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00
,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

const unsigned char partly_cloudy_day[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x0e, 0x00
, 0x00, 0x07, 0x80, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x3e, 0x00
, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x78, 0x00
, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00
, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00
, 0x00, 0x07, 0xe7, 0xe0, 0x7e, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x1f, 0x00, 0x00
, 0x00, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x07, 0x80, 0x00
, 0x07, 0xf0, 0x0f, 0xe0, 0x07, 0x80, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x03, 0xc0, 0x00
, 0x1f, 0x00, 0x00, 0xf8, 0x03, 0xc1, 0xf8, 0x1e, 0x00, 0x00, 0x78, 0x03, 0xc3, 0xfc
, 0x3c, 0x00, 0x00, 0x3f, 0xc3, 0xc3, 0xfc, 0x3c, 0x00, 0x00, 0x3f, 0xfb, 0xc1, 0xf8
, 0x78, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x78, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00
, 0x70, 0x00, 0x00, 0x08, 0x1f, 0x80, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00
, 0xf0, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00
, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00
, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00
, 0x78, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00
, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00
, 0x1e, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00
, 0x0f, 0xc0, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x1f, 0x80, 0x00
, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00
, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00
};

GxEPD2_BW&lt;GxEPD2_420, GxEPD2_420::HEIGHT&gt; display(GxEPD2_420(/*CS=D8*/ EPD_CS, /*DC=D3*/ 16, /*RST=D4*/ 5, /*BUSY=D2*/ 19));

char ssid[] = "xxxxxx"; // Your network SSID (name)
char password[] = "xxxxxxxx"; // Your network key
char host[] = "192.168.178.100"; // IP of SmartHomeNG
int port = 4321;

WiFiClient client;
JsonParser&lt;32&gt; parser;
String currentLine = "";
String currRates = "";
boolean readingJson = false;
#define BUFFERSIZE 5800
static char inData[BUFFERSIZE + 1]; // string + terminator

void setup(void) {
  Serial.begin(115200);
  initialise_wifi();
  display.init(115200);
}

void loop() {
  connect_to_server();
  Serial.println("new loop");
  if (client.connected())
  {
    Serial.println("[isConnected]");
    int index = 0;
    while (!client.available()) {}
    while (client.available()) {
      char inChar = client.read();
      if (inChar == '{') {
        readingJson = true;
      }
      if (readingJson) {
        if (index &lt; BUFFERSIZE - 1)
        {
          inData[index] = inChar; // Store it
          index++;
        }
        if (inChar == '}') {
          readingJson = false;
          inData[index] = '\0';
        }
      }
    }
    client.stop();
    Serial.println("[Disconnected]");
     
    // JSON Daten parsen
    StaticJsonBuffer&lt;5800&gt; jsonBuffer;
    JsonObject&amp; root = jsonBuffer.parseObject(inData);
    if (!root.success())
    {
      Serial.print("parseObject(");
      Serial.print(inData);
      Serial.println(") failed");
    } else {
      Serial.println("[Parse Success]");
      printJsonData(root);
    }
  }
  delay(1000 * 60 * 10); // 10 Minuten warten
}

void printJsonData(JsonObject&amp; root)
{
  int dateSubstringStart = 11;
  int dateSubstringEnd = 16;
  double ozone = root["weather.darksky.home.currently.ozone"];
  String uvIndex = root["weather.darksky.home.currently.uvIndex"];
  String uvIndexStr = root["weather.darksky.home.currently.uvIndex.string"];
  uvIndexStr.replace("u00e4", "ae");
  uvIndexStr.replace("u00df", "ss");
  String curTime = root["weather.darksky.home.currently.time.timeStr"];
  String curDate = root["weather.darksky.home.currently.time.dateStr"];
  double outsideHumidity = root["weather.darksky.home.currently.humidity"];
  double surplus = root["sma.smaem.surplus.kw"];
  double regard = root["sma.smaem.regard.kw"];
  double precipProb = root["weather.darksky.home.currently.precipProbability"];
  double pressure = root["weather.darksky.home.currently.pressure"];
  String currentIcon = root["weather.darksky.home.currently.icon"];
  String moonLight = root["env.location.moonlight"];
  String knx_light_status = root["knx.light_status"];
  String gate_state = root["knx.outside.gate.driveway.state"];
  String moonRise = root["env.location.moonrise"];
  moonRise = moonRise.substring(dateSubstringStart, dateSubstringEnd);
  String moonSet = root["env.location.moonset"];
  moonSet = moonSet.substring(dateSubstringStart, dateSubstringEnd);
  String moonPhase = root["env.location.moonphase"];
  String sunSet = root["env.location.sunset"];
  sunSet = sunSet.substring(dateSubstringStart, dateSubstringEnd);;
  String sunRise = root["env.location.sunrise"];
  sunRise = sunRise.substring(dateSubstringStart, dateSubstringEnd);
  String temperature = root["eta_unit.temperature_outside.value"];
  String temperatureMin = root["eta_unit.temperature_outside.value.min_24"];
  String temperatureMax = root["eta_unit.temperature_outside.value.max_24"];
  String currentlySummary = root["weather.darksky.home.currently.summary"];
  String dailySummary = root["weather.darksky.home.daily.summary"];
  double windSpeed = root["weather.darksky.home.currently.windSpeed"];
  dailySummary.replace("u00b0C", " Grad");
  dailySummary.replace("u00e4", "ae");
  display.setRotation(2);
  display.setFont(&amp;FreeMonoBold18pt7b);
  display.setTextColor(GxEPD_BLACK);
  display.setFullWindow();
  display.firstPage();

  do
  {
    display.fillScreen(GxEPD_WHITE);
    display.setFont(&amp;FreeMonoBold9pt7b);

    display.setCursor(0, 11); display.println(curTime);
    display.setCursor(150, 11); display.println("Mein Ort");
    display.setCursor(290, 11); display.println(curDate);
    drawDashedHLine(0, 20, 420, GxEPD_BLACK);

    display_icon(330, 25, currentIcon);
    display.setCursor(270, 42);
    if (surplus &gt; 0) {
      display.println(surplus);
    } else {
      display.println((-1)*regard);
    }
    display.setCursor(270, 62); display.println("kW");
    display.setCursor(270, 100); display.println("UV: "+uvIndex);
    display.setCursor(270, 115); display.println(uvIndexStr);
    display.setCursor(270, 140); display.print("Ozon: "); display.println((int)ozone, DEC);

    display.setFont(&amp;FreeMonoBold12pt7b);
    dashedRect(0,25,260,125, GxEPD_BLACK);
    display_icon(2, 25, "temperature");
    display.setCursor(50, 47); display.println(temperature+" Grad");
    display.setCursor(50, 67); display.print(outsideHumidity*100,0); display.println("%");
    display_icon(2, 65, "prob_rain");
    display.setCursor(50, 98); display.print(precipProb*100,0); display.println("%");
    display_icon(100, 76, "wind_speed");
    display.setCursor(140, 98); display.print((int)windSpeed, DEC); display.println("km/h");

    //display.setFont(&amp;FreeMonoBold9pt7b);
    display_icon(15, 113, "barometer");
    display.setCursor(50, 135); display.print((int)pressure, DEC); display.println("hPa");

    display.setFont(&amp;FreeMonoBold9pt7b);
    drawDashedHLine(0, 155, 420, GxEPD_BLACK);
    display.setCursor(0, 170); display.println(dailySummary);
    drawDashedHLine(0, 220, 420, GxEPD_BLACK);
    display.setFont(&amp;FreeMonoBold9pt7b);
    display_icon(0, 255, "sunrise_sunset");
    display.setCursor(60, 275); display.println(sunRise);
    display.setCursor(60, 289); display.println(sunSet);
    display.setFont(&amp;FreeMonoBold18pt7b);
    display_icon(137, 265, "moon_"+moonPhase);
    display.setFont(&amp;FreeMonoBold9pt7b);
    display.setCursor(170, 275); display.println(moonRise);
    display.setCursor(170, 289); display.println(moonSet);
    display.setCursor(260, 242); display.println("Tor:");
    
    if (gate_state.equals("false")) {
      display_icon(257, 249, "gate_closed");
    } else {
      display_icon(257, 249, "gate_open");
    }
    display.setCursor(325, 242); display.println("Licht:");
    if (knx_light_status.equals("false")) {
      display_icon(330, 247, "light_off");
    } else {
      display_icon(330, 247, "light_on");
    }
  }
  while (display.nextPage());
}

void drawDashedHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
  display.startWrite();
  writeDashedLine(x, y, x + w - 1, y, color);
  display.endWrite();
}

#ifndef _swap_int16_t
#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }
#endif

void writeDashedLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {
  int16_t steep = abs(y1 - y0) &gt; abs(x1 - x0);
  bool hole = false; //make it dash by using a hole every second pixel
  if (steep) {
    _swap_int16_t(x0, y0);
    _swap_int16_t(x1, y1);
  }

  if (x0 &gt; x1) {
    _swap_int16_t(x0, x1);
    _swap_int16_t(y0, y1);
  }

  int16_t dx, dy;
  dx = x1 - x0;
  dy = abs(y1 - y0);

  int16_t err = dx / 2;
  int16_t ystep;

  if (y0 &lt; y1) {
    ystep = 1;
  }
  else {
    ystep = -1;
  }

  for (; x0 &lt;= x1; x0++) {
    if (steep) {
      if (!hole) display.writePixel(y0, x0, color);
      hole = !hole;
    } else {
      if (!hole) display.writePixel(x0, y0, color);
      hole = !hole;
    }
    err -= dy;
    if (err &lt; 0) {
      y0 += ystep;
      err += dx;
    }
  }
}

void dashedRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
  display.startWrite();
  writeDashedLine(x, y, x + w - 1, y, color);
  writeDashedLine(x, y, x, y + h - 1, color);
  writeDashedLine(x + w - 1, y, x + w - 1, y + h - 1, color);
  writeDashedLine(x, y + h - 1, x + w - 1, y + h - 1, color);
  display.endWrite();
}

void display_icon(int x, int y, String icon_name) {
  int scale = 10; // Adjust size as necessary
  if (icon_name == "partly-cloudy-day")
    display.drawBitmap(x, y, partly_cloudy_day, 54, 50, GxEPD_BLACK);
  else if (icon_name == "clear-day")
    display.drawBitmap(x, y, clear_day, 54, 50, GxEPD_BLACK);
  else if (icon_name == "rain")
    display.drawBitmap(x, y, rain, 54, 50, GxEPD_BLACK);
  else if (icon_name == "sunrise_sunset")
    display.drawBitmap(x, y, sunrise_sunset, 48, 36, GxEPD_BLACK);
  else if (icon_name == "prob_rain")
    display.drawBitmap(x, y, prob_rain, 54, 50, GxEPD_BLACK);
  else if (icon_name == "temperature")
    display.drawBitmap(x, y, temperature, 54, 50, GxEPD_BLACK);
  else if (icon_name == "pressure")
    display.drawBitmap(x, y, pressure, 69, 64, GxEPD_BLACK);
  else if (icon_name == "moon_0")
    display.drawBitmap(x, y, moon_0_8, 24, 24, GxEPD_BLACK);
  else if (icon_name == "moon_1")
    display.drawBitmap(x, y, moon_2, 24, 24, GxEPD_BLACK);
  else if (icon_name == "moon_2")
    display.drawBitmap(x, y, moon_3, 24, 24, GxEPD_BLACK);
  else if (icon_name == "moon_3")
    display.drawBitmap(x, y, moon_4, 24, 24, GxEPD_BLACK);
  else if (icon_name == "moon_4")
    display.drawBitmap(x, y, moon_5, 24, 24, GxEPD_BLACK);
  else if (icon_name == "moon_5")
    display.drawBitmap(x, y, moon_6, 24, 24, GxEPD_BLACK);
  else if (icon_name == "moon_6")
    display.drawBitmap(x, y, moon_7, 24, 24, GxEPD_BLACK);
  else if (icon_name == "moon_7")
    display.drawBitmap(x, y, moon_8, 24, 24, GxEPD_BLACK);
  else if (icon_name == "moon_8")
    display.drawBitmap(x, y, moon_0_8, 24, 24, GxEPD_BLACK);
  else if (icon_name == "barometer")
    display.drawBitmap(x, y, barometer, 30, 30, GxEPD_BLACK);
  else if (icon_name == "wind_speed")
    display.drawBitmap(x, y, wind_speed, 30, 30, GxEPD_BLACK);
  else if (icon_name == "light_on")
    display.drawBitmap(x, y, light_on, 50, 50, GxEPD_BLACK);
  else if (icon_name == "light_off")
    display.drawBitmap(x, y, light_off, 50, 50, GxEPD_BLACK);
  else if (icon_name == "gate_open")
    display.drawBitmap(x, y, gate_open, 50, 50, GxEPD_BLACK);
  else if (icon_name == "gate_closed")
    display.drawBitmap(x, y, gate_closed, 47, 50, GxEPD_BLACK);
}

// NETWORK STUFF

void connect_to_server() {
  if (client.connect(host, port)) {
    Serial.println("[Connected to server]");
    // HTTP Request gegen SmartHomeNG / das Webservices-Plugin durchführen
    client.println("GET /rest/itemset/weather/ HTTP/1.0");
    //client.println("Host: 192.168.178.100");
    client.println();
  }
  else
  {
    Serial.println("[Connection Failed!]");
    client.stop();
  }
}

static void initialise_wifi(void)
{
  // Versuche ins WiFi Netzwerk zu verbinden
  int connAttempts = 0;
  Serial.print(F("\r\nConnecting to: "));
  Serial.println(String(ssid));
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000); Serial.print(".");
  if (connAttempts &gt; 30) return;
    connAttempts++;
  }
  Serial.println("Connected to wifi");
  print_wifi_status();
}

void print_wifi_status() {
  // SSID des WiFi Netzwerkes ausgeben:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // WiFi IP Adresse des ESP32 ausgeben:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // WiFi Signalstärke ausgeben:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}
</code></pre>
<p>Lädt man das Programm nun auf den verkabelten ESP32 hoch, erscheint nach kurzer Zeit folgende Ausgabe. Nach 10 Minuten erfolgt ein automatischer Refresh:</p>
<p><img loading="lazy" decoding="async" src="https://www.smarthomeng.de/wp-content/uploads/2018/07/result_epaper.jpg" alt="" width="1082" height="770" class="alignnone size-full wp-image-1944" srcset="https://www.smarthomeng.de/wp-content/uploads/2018/07/result_epaper.jpg 1082w, https://www.smarthomeng.de/wp-content/uploads/2018/07/result_epaper-300x213.jpg 300w, https://www.smarthomeng.de/wp-content/uploads/2018/07/result_epaper-768x547.jpg 768w, https://www.smarthomeng.de/wp-content/uploads/2018/07/result_epaper-1024x729.jpg 1024w" sizes="(max-width: 1082px) 100vw, 1082px" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smarthomeng.de/epaper-wetterstation-mit-daten-aus-smarthomeng/feed</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
	</channel>
</rss>
