<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://tippvomtibb.de/wiki/index.php?action=history&amp;feed=atom&amp;title=WLAN_Aktor_Markise</id>
	<title>WLAN Aktor Markise - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://tippvomtibb.de/wiki/index.php?action=history&amp;feed=atom&amp;title=WLAN_Aktor_Markise"/>
	<link rel="alternate" type="text/html" href="https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;action=history"/>
	<updated>2026-06-18T11:08:17Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in TippvomTibb</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;diff=4918&amp;oldid=prev</id>
		<title>Chris T. Ludwig: /* Fehlerquellen */</title>
		<link rel="alternate" type="text/html" href="https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;diff=4918&amp;oldid=prev"/>
		<updated>2026-06-13T15:55:01Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Fehlerquellen&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version vom 13. Juni 2026, 17:55 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l680&quot;&gt;Zeile 680:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 680:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Fehlerquellen==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Fehlerquellen==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Ja, es gibt einige relevante Fehlerquellen:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;1. **Speicherleck in `callback()`**&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;   `malloc(length)` wird nie mit `free(p)` freigegeben. Bei jedem MQTT-Befehl geht RAM verloren. Außerdem wird kein Byte für `\0` reserviert. Besser ganz ohne `malloc`:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;```cpp&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;String payloadStr((char*)payload, length);&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;```&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;2. **`state` ist nicht initialisiert**&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;   `volatile byte state;` bekommt keinen Startwert. Beim ersten Trigger kann der Zustand undefiniert sein. Besser:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;```cpp&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;volatile byte state = 0;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;```&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;3. **Richtungsbefehl setzt `state` nicht passend**&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;   Bei `direction == 1/2/3` werden Relais geschaltet, aber `state` wird nicht auf 1, 3 oder 0/2 gesetzt. Danach kann der nächste `trigger` falsch reagieren. &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;4. **Alte Timer laufen weiter**&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;   Wenn Richtung 1 gestartet wurde und danach Richtung 2 kommt, wird `startTimeDir1` nicht gelöscht. Später kann der alte Fallback unerwartet beide Relais ausschalten. Gleiches umgekehrt. &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;5. **Prüfung `maxTime[0] &amp;gt;= 0` ist wirkungslos**&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;   `maxTime` ist `unsigned long`, also nie negativ. Wenn `strtol()` einen negativen Wert liefert, wird er beim Speichern in `unsigned long` zu einem großen Wert. &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;6. **`sendRelaisCommand()` prüft Relaisnummer nicht**&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;   Bei versehentlich `sendRelaisCommand(0, ...)` oder `3` greift `relaisState[relais-1]` außerhalb des Arrays. Besser am Anfang:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;```cpp&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;if (relais &amp;lt; 1 || relais &amp;gt; 2) return;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;```&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;7. **Blockierende `delay()`-Aufrufe**&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;   Während `delay(500)` oder beim MQTT-Reconnect mit `delay(5000)` reagiert der Controller verzögert. Für eine Markise ist das noch akzeptabel, aber ein sofortiger Stopp kann dadurch verspätet kommen. &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;8. **MQTT ohne Authentifizierung**&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;   Der Code verbindet sich nur mit `MQTTClient.connect(mac.c_str())`. Jeder im Netz, der die Topics kennt, könnte die Markise steuern. &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Die wichtigsten Sofortkorrekturen wären: `state = 0`, `malloc` entfernen, Timer gegenseitig zurücksetzen, `state` bei Direktbefehlen aktualisieren und MQTT mit Benutzer/Passwort absichern.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Chris T. Ludwig</name></author>
	</entry>
	<entry>
		<id>https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;diff=4917&amp;oldid=prev</id>
		<title>Chris T. Ludwig: /* Software-Beschreibung */</title>
		<link rel="alternate" type="text/html" href="https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;diff=4917&amp;oldid=prev"/>
		<updated>2026-06-13T15:54:45Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Software-Beschreibung&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version vom 13. Juni 2026, 17:54 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l480&quot;&gt;Zeile 480:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 480:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Software-&lt;/del&gt;Beschreibung=&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=&lt;/ins&gt;Beschreibung&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=&lt;/ins&gt;=&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Die Software ist eine Firmware für einen **ESP8266 (ESP-01)**, die über MQTT eine **motorisierte Markise** oder einen ähnlichen Sonnenschutz steuert.  &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Die Software ist eine Firmware für einen **ESP8266 (ESP-01)**, die über MQTT eine **motorisierte Markise** oder einen ähnlichen Sonnenschutz steuert.  &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l678&quot;&gt;Zeile 678:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 678:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Der Aufbau wirkt wie ein typisches Smart-Home-Projekt zur Nachrüstung einer vorhandenen Funk- oder Tastersteuerung einer Terrasse-Markise.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Der Aufbau wirkt wie ein typisches Smart-Home-Projekt zur Nachrüstung einer vorhandenen Funk- oder Tastersteuerung einer Terrasse-Markise.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==Fehlerquellen==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Chris T. Ludwig</name></author>
	</entry>
	<entry>
		<id>https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;diff=4916&amp;oldid=prev</id>
		<title>Chris T. Ludwig: /* Software */</title>
		<link rel="alternate" type="text/html" href="https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;diff=4916&amp;oldid=prev"/>
		<updated>2026-06-13T15:52:37Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Software&lt;/span&gt;&lt;/p&gt;
&lt;a href=&quot;https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;amp;diff=4916&amp;amp;oldid=4915&quot;&gt;Änderungen zeigen&lt;/a&gt;</summary>
		<author><name>Chris T. Ludwig</name></author>
	</entry>
	<entry>
		<id>https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;diff=4915&amp;oldid=prev</id>
		<title>Chris T. Ludwig: Die Seite wurde neu angelegt: „=Allgemeines= Leider hatte ich keinen Port mehr an den KNX-Rollladenaktoren zur Verfuegung, daher bin ich auf eine MQTT-WLAN-ESP-DuoRelais-Schaltung ausgewischen.  =Hardware=   =Software=  &lt;syntaxhighlight lang=&quot;c&quot; line&gt;   //ShutterBlindsAwningFunction with LC-Relay-ESP01-2R-5V //tested 2022-08-06  #include &lt;ESP8266WiFi.h&gt;        // Include the Wi-Fi library #include &lt;PubSubClient.h&gt;       // MQTT #include &quot;ESPDateTime.h&quot;        // NTP #include &lt;ESP_EEPRO…“</title>
		<link rel="alternate" type="text/html" href="https://tippvomtibb.de/wiki/index.php?title=WLAN_Aktor_Markise&amp;diff=4915&amp;oldid=prev"/>
		<updated>2026-06-13T15:49:28Z</updated>

		<summary type="html">&lt;p&gt;Die Seite wurde neu angelegt: „=Allgemeines= Leider hatte ich keinen Port mehr an den KNX-Rollladenaktoren zur Verfuegung, daher bin ich auf eine MQTT-WLAN-ESP-DuoRelais-Schaltung ausgewischen.  =Hardware=   =Software=  &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;   //ShutterBlindsAwningFunction with LC-Relay-ESP01-2R-5V //tested 2022-08-06  #include &amp;lt;ESP8266WiFi.h&amp;gt;        // Include the Wi-Fi library #include &amp;lt;PubSubClient.h&amp;gt;       // MQTT #include &amp;quot;ESPDateTime.h&amp;quot;        // NTP #include &amp;lt;ESP_EEPRO…“&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;=Allgemeines=&lt;br /&gt;
Leider hatte ich keinen Port mehr an den KNX-Rollladenaktoren zur Verfuegung, daher bin ich auf eine MQTT-WLAN-ESP-DuoRelais-Schaltung ausgewischen.&lt;br /&gt;
&lt;br /&gt;
=Hardware=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Software=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
//ShutterBlindsAwningFunction with LC-Relay-ESP01-2R-5V&lt;br /&gt;
//tested 2022-08-06&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;ESP8266WiFi.h&amp;gt;        // Include the Wi-Fi library&lt;br /&gt;
#include &amp;lt;PubSubClient.h&amp;gt;       // MQTT&lt;br /&gt;
#include &amp;quot;ESPDateTime.h&amp;quot;        // NTP&lt;br /&gt;
#include &amp;lt;ESP_EEPROM.h&amp;gt;         // to store non-volatile variables&lt;br /&gt;
#include &amp;quot;CRC.h&amp;quot;                // to check the reliability of the EEPROM-stored variables&lt;br /&gt;
#include &amp;quot;CRC8.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//CONFIGURATION&lt;br /&gt;
#define WLAN_SSID &amp;quot;XXX&amp;quot;&lt;br /&gt;
#define WLAN_PASSWORD &amp;quot;YYY&amp;quot;&lt;br /&gt;
#define MQTT_SERVER_IP &amp;quot;ZZZ&amp;quot;  // better to use the ip, DNS will slow down the speed&lt;br /&gt;
#define MQTT_MSG_BUFFER_SIZE	50&lt;br /&gt;
#define MQTT_DEBUG_MSG_BUFFER_SIZE 50&lt;br /&gt;
#define MQTTT_BASE_TOPIC &amp;quot;home/basement/0_terrace/awning/&amp;quot;  // my rooms are numbered so there is a consideration to replace the _ with / to use the 0 also for e.g. garden&lt;br /&gt;
#define MQTT_OUT_STATE MQTTT_BASE_TOPIC &amp;quot;state&amp;quot;&lt;br /&gt;
#define MQTT_OUT_RAW MQTTT_BASE_TOPIC &amp;quot;raw&amp;quot;&lt;br /&gt;
#define MQTT_OUT_ALIVE MQTTT_BASE_TOPIC &amp;quot;alive&amp;quot;&lt;br /&gt;
#define MQTT_OUT_RSSI MQTTT_BASE_TOPIC &amp;quot;RSSI&amp;quot;&lt;br /&gt;
#define MQTT_IN_TRIGGER MQTTT_BASE_TOPIC &amp;quot;trigger&amp;quot;&lt;br /&gt;
#define MQTT_IN_DIRECTION MQTTT_BASE_TOPIC &amp;quot;direction&amp;quot;&lt;br /&gt;
#define MQTT_IN_CONFIG MQTTT_BASE_TOPIC &amp;quot;config&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//#define SERIAL_DEBUG          // used in an early stage of development; conflicts with UART output for relais control&lt;br /&gt;
#define MQTT_DEBUG_OUTPUT     // the raw topic serves to output the values for debugging // TODO struct config&lt;br /&gt;
#define ALIVEINTERVAL 10000     // UpdateInterval in milliseconds of the topics &amp;#039;alive&amp;#039; // TODO struct config&lt;br /&gt;
&lt;br /&gt;
//WIFI&lt;br /&gt;
WiFiClient espClient;&lt;br /&gt;
const char * ssid     = WLAN_SSID;         // The SSID (name) of the Wi-Fi network you want to connect to&lt;br /&gt;
const char * password = WLAN_PASSWORD;     // The password of the Wi-Fi network&lt;br /&gt;
String mac;&lt;br /&gt;
&lt;br /&gt;
//MQTT&lt;br /&gt;
const char * MQTTServer = MQTT_SERVER_IP;&lt;br /&gt;
PubSubClient MQTTClient(espClient); //Constructor&lt;br /&gt;
unsigned long lastMsg = 0;  // to remember the last timestamp of the &amp;#039;ALVIE-publish&amp;#039; (heartbeat)&lt;br /&gt;
char msg[MQTT_MSG_BUFFER_SIZE]; // old style; sorry for mixing c and c++&lt;br /&gt;
char msgConfig[MQTT_DEBUG_MSG_BUFFER_SIZE]; // to store the config parameters; in setup there is no possibility to send out, so store it to send it in loop&lt;br /&gt;
long int value = 0; // don&amp;#039;t needed anymore; its a counter replaced by DateTime&lt;br /&gt;
&lt;br /&gt;
String topicBase = MQTTT_BASE_TOPIC ;&lt;br /&gt;
String inConfigTopic = MQTT_IN_CONFIG ;&lt;br /&gt;
String inTriggerTopic = MQTT_IN_TRIGGER ;&lt;br /&gt;
String inDirectionTopic = MQTT_IN_DIRECTION;&lt;br /&gt;
String outStateTopic = MQTT_OUT_STATE ;&lt;br /&gt;
String outRawTopic = MQTT_OUT_RAW ;&lt;br /&gt;
String outAliveTopic = MQTT_OUT_ALIVE ;&lt;br /&gt;
String outRSSITopic = MQTT_OUT_RSSI ;&lt;br /&gt;
String clientId;&lt;br /&gt;
&lt;br /&gt;
//RELAIS&lt;br /&gt;
void sendRelaisCommand(unsigned int relais,boolean onoff); // forward declaration&lt;br /&gt;
volatile byte state; // 0 STOP (0,X); 1 EXTEND (1,1); 2 STOP (0,X); 3 RETRACT (1,0)&lt;br /&gt;
volatile boolean relaisState[] = {false,false};&lt;br /&gt;
struct EEPROMValues{ // use a struct to store and retrieve to/from EEPROM&lt;br /&gt;
  //const char* mark=&amp;quot;#&amp;quot;; // Before C++11, members of a struct could not be default initialized. Instead they must be initialized after an instance struct is created.&lt;br /&gt;
  //EEPROM.put/get probably have issues with strings&lt;br /&gt;
  byte mark;  //or char mark;&lt;br /&gt;
  unsigned long timeActiveDir1; // Milliseconds active till relaisstate[] falls back to {false,false}&lt;br /&gt;
  unsigned long timeActiveDir2; // Milliseconds active till relaisstate[] false back to {false,false}&lt;br /&gt;
  unsigned long checksum;&lt;br /&gt;
} settings;&lt;br /&gt;
&lt;br /&gt;
//TIMER&lt;br /&gt;
unsigned long startTimeDir1 = 0;  // Starttime if relais1 goes active&lt;br /&gt;
unsigned long startTimeDir2 = 0;  // Starttime if relais1 goes active&lt;br /&gt;
&lt;br /&gt;
//CRC&lt;br /&gt;
CRC8 crc;&lt;br /&gt;
unsigned int eepromAddr = 0;  // address to store the config variables, mark and checksum (struct settings)&lt;br /&gt;
&lt;br /&gt;
//CONFIG&lt;br /&gt;
boolean sendOutOneTime = false; // flag to output the stored config only once after powerup/reset&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//CALLBACK The function is called when a new message arrives. All code to react within this function and/or transfer the parameter to outer variables.&lt;br /&gt;
// mosquitto_pub -h 192.168.178.x -t &amp;#039;home/basement/0_terrace/awning/trigger&amp;#039; -m &amp;#039;1&amp;#039; // or -m 1 or -m 0&lt;br /&gt;
// mosquitto_pub -h 192.168.178.x -t &amp;#039;home/basement/0_terrace/awning/config&amp;#039; -m &amp;#039;7000 8000&amp;#039;&lt;br /&gt;
// mosquitto_pub -h 192.168.178.x -t &amp;#039;home/basement/0_terrace/awning/direction&amp;#039; -m &amp;#039;up&amp;#039;&lt;br /&gt;
void callback(char* topic, byte* payload, unsigned int length) { // topic ends with direction or config // payload from -m within apostrophes // lentgh integer number of bytes of payload&lt;br /&gt;
  #ifdef SERIAL_DEBUG&lt;br /&gt;
    Serial.print(&amp;quot;Message arrived [&amp;quot;);&lt;br /&gt;
    Serial.print(topic);&lt;br /&gt;
    Serial.print(&amp;quot;] &amp;quot;);&lt;br /&gt;
    for (unsigned int i = 0; i &amp;lt; length; i++) {&lt;br /&gt;
      Serial.print((char)payload[i]);  // print out the payload array byte by byte&lt;br /&gt;
    }&lt;br /&gt;
    Serial.println();&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  String payloadStr; // to transfer the byte-array to a String&lt;br /&gt;
  char* p = (char*)malloc(length); // copy the payload to the new buffer; actually not necessary&lt;br /&gt;
  memcpy(p,payload,length); // play safe, it does no harm&lt;br /&gt;
  payloadStr.concat(p,length); // String is better to do things like .toLowerCase();&lt;br /&gt;
&lt;br /&gt;
  // Trigger CONTROL&lt;br /&gt;
  if (strcmp(inTriggerTopic.c_str(),topic) == 0 &amp;amp;&amp;amp; (char)payload[0] == &amp;#039;1&amp;#039;) { //1 for trigger // 0 or other are not handled&lt;br /&gt;
    boolean stateSet = false; // if the state is detected and changed ignore all following state detections&lt;br /&gt;
    // Relais 1 determines the direction&lt;br /&gt;
    // Relais 2 switches on/off respectively move/stop&lt;br /&gt;
    // activating means first switch on relay 1, pause, activate relay 2&lt;br /&gt;
    // deactivating means first switch off relay 2, pause and only then relay 1 if necessary switch&lt;br /&gt;
    // state 0 both relays off (relay 2 then 1) start condition&lt;br /&gt;
    // state 1 relay 1 set relay 1 to move out/down postition, pause, activate relay 2&lt;br /&gt;
    // state 2 both relays off (relay 2 then 1) intermediate condition&lt;br /&gt;
    // state 3 relay 1 set relay 1 to move in/up postition, pause, activate relay 2&lt;br /&gt;
    // recommendation for pausetime is 500 ms&lt;br /&gt;
    if (!relaisState[0] &amp;amp;&amp;amp; !relaisState[1] &amp;amp;&amp;amp; state != 0 &amp;amp;&amp;amp; state !=2 ){ //asynchron!!! correct it&lt;br /&gt;
      state = 0;&lt;br /&gt;
      stateSet = true;&lt;br /&gt;
    }&lt;br /&gt;
    if (!relaisState[0] &amp;amp;&amp;amp; !relaisState[1] &amp;amp;&amp;amp; !stateSet){&lt;br /&gt;
      if(state==0){ // State 0-&amp;gt;1&lt;br /&gt;
        sendRelaisCommand(1,true); // extend&lt;br /&gt;
        delay(100);&lt;br /&gt;
        sendRelaisCommand(2,true); // activate&lt;br /&gt;
        state=1;&lt;br /&gt;
        startTimeDir1 = millis();&lt;br /&gt;
      }&lt;br /&gt;
      if(state==2){ // state 2-&amp;gt;3&lt;br /&gt;
        sendRelaisCommand(1,false); // retract&lt;br /&gt;
        delay(100);&lt;br /&gt;
        sendRelaisCommand(2,true);  // activate&lt;br /&gt;
        state=3;&lt;br /&gt;
        startTimeDir2 = millis();&lt;br /&gt;
      }&lt;br /&gt;
      stateSet = true;&lt;br /&gt;
    }&lt;br /&gt;
    if (relaisState[0] &amp;amp;&amp;amp; relaisState[1] &amp;amp;&amp;amp; !stateSet){ // state 1-&amp;gt;2&lt;br /&gt;
      sendRelaisCommand(2,false);&lt;br /&gt;
      delay(100);&lt;br /&gt;
      sendRelaisCommand(1,false); //at this point the relais could be untouched, in state 1 and 3 it will be set again, to save energy switch both relays to off&lt;br /&gt;
      state=2;&lt;br /&gt;
      stateSet = true;&lt;br /&gt;
    }&lt;br /&gt;
    if (!relaisState[0] &amp;amp;&amp;amp; relaisState[1] &amp;amp;&amp;amp; !stateSet){ // state 3-&amp;gt;0&lt;br /&gt;
      sendRelaisCommand(2,false);&lt;br /&gt;
      delay(100);&lt;br /&gt;
      sendRelaisCommand(1,false); //at this point the relais could be untouched, in state 1 and 3 it will be set again, to save energy switch both relays to off&lt;br /&gt;
      state=0;&lt;br /&gt;
      stateSet = true;&lt;br /&gt;
    }&lt;br /&gt;
    snprintf (msg, MQTT_DEBUG_MSG_BUFFER_SIZE, &amp;quot;%d&amp;quot;,state);&lt;br /&gt;
    #ifdef SERIAL_DEBUG&lt;br /&gt;
     Serial.print(&amp;quot;Publish message: &amp;quot;);&lt;br /&gt;
     Serial.println(msg);&lt;br /&gt;
    #endif&lt;br /&gt;
    MQTTClient.publish(outStateTopic.c_str(), msg);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Direction CONTROL&lt;br /&gt;
  if (strcmp(inDirectionTopic.c_str(),topic) == 0) {&lt;br /&gt;
    uint8_t direction=0; // 1 means down(out); 2 means up(in)&lt;br /&gt;
    payloadStr.toLowerCase();&lt;br /&gt;
    //MQTTClient.publish(outRawTopic.c_str(), payloadStr.c_str());&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    const char directions1[3][6]={&amp;quot;down&amp;quot;,&amp;quot;out&amp;quot;,&amp;quot;on&amp;quot;}; // to react to all of this commands&lt;br /&gt;
    const char directions2[3][6]={&amp;quot;up&amp;quot;,&amp;quot;in&amp;quot;,&amp;quot;off&amp;quot;};&lt;br /&gt;
    const char directions3[3][6]={&amp;quot;halt&amp;quot;,&amp;quot;stop&amp;quot;,&amp;quot;stopp&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
    uint8_t number; // -Wunused-but-set-variable&lt;br /&gt;
    number=sizeof(directions1)/sizeof(directions1[0]); // calculate the number of array members  // Test!!! can be deleted&lt;br /&gt;
    (void)number; // to suppress the warning&lt;br /&gt;
    #ifdef MQTT_DEBUG_OUTPUT&lt;br /&gt;
      snprintf (msg, MQTT_DEBUG_MSG_BUFFER_SIZE, &amp;quot;%d&amp;quot;,number);&lt;br /&gt;
      MQTTClient.publish(outRawTopic.c_str(), msg);&lt;br /&gt;
    #endif&lt;br /&gt;
&lt;br /&gt;
    // only one of this tests can be true // after this block direction is 1, 2 or 3 depending on command&lt;br /&gt;
    for(uint8_t i=1;i&amp;lt;=(sizeof(directions1)/sizeof(directions1[0]));i++){&lt;br /&gt;
      if (strcmp(payloadStr.c_str(),directions1[i-1])==0)direction=1;&lt;br /&gt;
    }&lt;br /&gt;
    for(uint8_t i=1;i&amp;lt;=(sizeof(directions2)/sizeof(directions2[0]));i++){&lt;br /&gt;
      if (strcmp(payloadStr.c_str(),directions2[i-1])==0)direction=2;&lt;br /&gt;
    }&lt;br /&gt;
    for(uint8_t i=1;i&amp;lt;=(sizeof(directions3)/sizeof(directions3[0]));i++){&lt;br /&gt;
      if (strcmp(payloadStr.c_str(),directions3[i-1])==0)direction=3;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (direction == 1){&lt;br /&gt;
      MQTTClient.publish(outRawTopic.c_str(), &amp;quot;DIR1&amp;quot;);&lt;br /&gt;
      sendRelaisCommand(2,false);&lt;br /&gt;
      delay(100);&lt;br /&gt;
      sendRelaisCommand(1,false);&lt;br /&gt;
      delay(500);&lt;br /&gt;
      sendRelaisCommand(1,true); // move out/down&lt;br /&gt;
      delay(100);&lt;br /&gt;
      sendRelaisCommand(2,true); // activate&lt;br /&gt;
      startTimeDir1 = millis();&lt;br /&gt;
    }&lt;br /&gt;
    if (direction == 2){&lt;br /&gt;
      MQTTClient.publish(outRawTopic.c_str(), &amp;quot;DIR2&amp;quot;);&lt;br /&gt;
      sendRelaisCommand(2,false);&lt;br /&gt;
      delay(100);&lt;br /&gt;
      sendRelaisCommand(1,false);&lt;br /&gt;
      delay(500);&lt;br /&gt;
      sendRelaisCommand(1,false);&lt;br /&gt;
      delay(100);&lt;br /&gt;
      sendRelaisCommand(2,true);&lt;br /&gt;
      startTimeDir2 = millis();&lt;br /&gt;
    }&lt;br /&gt;
    if (direction == 3){&lt;br /&gt;
      MQTTClient.publish(outRawTopic.c_str(), &amp;quot;DIR3&amp;quot;);&lt;br /&gt;
      sendRelaisCommand(2,false);&lt;br /&gt;
      delay(100);&lt;br /&gt;
      sendRelaisCommand(1,false);&lt;br /&gt;
      delay(500);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // config CONTROL&lt;br /&gt;
  if (strcmp(inConfigTopic.c_str(),topic) == 0){&lt;br /&gt;
    unsigned long maxTime[] = {180,180};&lt;br /&gt;
    const char* pL = payloadStr.c_str();  // get pointer to payload string // the payload is the combination of two integer space separated&lt;br /&gt;
    char* end;                            // declare a pointer&lt;br /&gt;
    for (uint8_t i = 1; i &amp;lt;= 2; i++){&lt;br /&gt;
      maxTime[i-1] = strtol(pL,&amp;amp;end,10); // &amp;amp;end is the reference to an object of type char*, whose value is set by the function to the next character in str after the numerical value.&lt;br /&gt;
      if (pL == end) break;&lt;br /&gt;
      pL = end; // the space at the beginning of second number is seemingly not a problem&lt;br /&gt;
    }&lt;br /&gt;
    snprintf (msg, MQTT_DEBUG_MSG_BUFFER_SIZE, &amp;quot;{%ld:%ld}&amp;quot;,maxTime[0],maxTime[1]);&lt;br /&gt;
    MQTTClient.publish(outRawTopic.c_str(), msg);&lt;br /&gt;
    if (maxTime[0]&amp;gt;=0 &amp;amp;&amp;amp; maxTime[0]&amp;lt;=1440000 &amp;amp;&amp;amp; maxTime[1]&amp;gt;=0 &amp;amp;&amp;amp; maxTime[1]&amp;lt;=1440000){&lt;br /&gt;
      settings.timeActiveDir1=maxTime[0];&lt;br /&gt;
      settings.timeActiveDir2=maxTime[1];&lt;br /&gt;
      crc.reset();&lt;br /&gt;
      crc.add(settings.timeActiveDir1);&lt;br /&gt;
      crc.add(settings.timeActiveDir2);&lt;br /&gt;
      settings.checksum=crc.getCRC();&lt;br /&gt;
      #ifdef MQTT_DEBUG_OUTPUT&lt;br /&gt;
        snprintf (msg, MQTT_DEBUG_MSG_BUFFER_SIZE, &amp;quot;{EEPROMput:%c:%ld:%ld:%ld}&amp;quot;,settings.mark,settings.timeActiveDir1,settings.timeActiveDir2,settings.checksum);&lt;br /&gt;
        MQTTClient.publish(outRawTopic.c_str(), msg);&lt;br /&gt;
      #endif&lt;br /&gt;
      EEPROM.put(eepromAddr, settings); //write data to array in ram&lt;br /&gt;
      EEPROM.commit();  //write data from ram to flash memory. Do nothing if there are no changes to EEPROM data in ram&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void reconnect() {&lt;br /&gt;
  // Loop until we&amp;#039;re reconnected&lt;br /&gt;
  while (!MQTTClient.connected()) {&lt;br /&gt;
    #ifdef SERIAL_DEBUG&lt;br /&gt;
      Serial.print(&amp;quot;Attempting MQTT connection...&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
&lt;br /&gt;
    // Attempt to connect&lt;br /&gt;
    if (MQTTClient.connect(mac.c_str()))  {&lt;br /&gt;
      #ifdef SERIAL_DEBUG&lt;br /&gt;
          Serial.println(&amp;quot;connected&amp;quot;);&lt;br /&gt;
      #endif&lt;br /&gt;
      // Once connected, publish an announcement...&lt;br /&gt;
      MQTTClient.publish(topicBase.c_str(), &amp;quot;CON&amp;quot;);&lt;br /&gt;
      // ... and resubscribe&lt;br /&gt;
      MQTTClient.subscribe(inTriggerTopic.c_str());&lt;br /&gt;
      MQTTClient.subscribe(inDirectionTopic.c_str());&lt;br /&gt;
      MQTTClient.subscribe(inConfigTopic.c_str());&lt;br /&gt;
    } else {&lt;br /&gt;
      #ifdef SERIAL_DEBUG&lt;br /&gt;
        Serial.print(&amp;quot;failed, rc=&amp;quot;);&lt;br /&gt;
        Serial.print(MQTTClient.state());&lt;br /&gt;
        Serial.println(&amp;quot; try again in 5 seconds&amp;quot;);&lt;br /&gt;
      #endif&lt;br /&gt;
      // Wait 5 seconds before retrying&lt;br /&gt;
      delay(5000);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void sendRelaisCommand(unsigned int relais,boolean onoff){&lt;br /&gt;
  //default for relais 1&lt;br /&gt;
  byte commandOn[4]={160,1,1,162};  // A0 (160 Non-breaking space) command initiate, relay 1/2, on/off, checksum (Addition)&lt;br /&gt;
  byte commandOff[4]={160,1,0,161};&lt;br /&gt;
&lt;br /&gt;
  //change commands for relais 2&lt;br /&gt;
  if (relais==2){&lt;br /&gt;
      commandOn[1]=2;&lt;br /&gt;
      commandOff[1]=2;&lt;br /&gt;
      commandOn[3]=163;&lt;br /&gt;
      commandOff[3]=162;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (onoff){&lt;br /&gt;
      Serial.write(commandOn,4);&lt;br /&gt;
      relaisState[relais-1]=true;&lt;br /&gt;
  }else{&lt;br /&gt;
      Serial.write(commandOff,4);&lt;br /&gt;
      relaisState[relais-1]=false;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  #ifdef MQTT_DEBUG_OUTPUT&lt;br /&gt;
    snprintf (msg, MQTT_DEBUG_MSG_BUFFER_SIZE, &amp;quot;RELAIS-%d_SET_%s&amp;quot;,relais,onoff?&amp;quot;ON&amp;quot;:&amp;quot;OFF&amp;quot;);&lt;br /&gt;
    #ifdef SERIAL_DEBUG&lt;br /&gt;
     Serial.print(&amp;quot;Publish message: &amp;quot;);&lt;br /&gt;
     Serial.println(msg);&lt;br /&gt;
    #endif&lt;br /&gt;
    MQTTClient.publish(outRawTopic.c_str(),msg);&lt;br /&gt;
  #endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setupDateTime() {&lt;br /&gt;
  // setup this after wifi connected&lt;br /&gt;
  // you can use custom timeZone,server and timeout&lt;br /&gt;
  // DateTime.setTimeZone(-4);&lt;br /&gt;
  //   DateTime.setServer(&amp;quot;asia.pool.ntp.org&amp;quot;);&lt;br /&gt;
  //   DateTime.begin(15 * 1000);&lt;br /&gt;
  DateTime.setServer(&amp;quot;de.pool.ntp.org&amp;quot;);&lt;br /&gt;
  DateTime.setTimeZone(&amp;quot;CEST&amp;quot;);&lt;br /&gt;
  DateTime.begin(); // ( 	const unsigned int  	timeOutMs = DEFAULT_TIMEOUT	)&lt;br /&gt;
  #ifdef SERIAL_DEBUG&lt;br /&gt;
    if (!DateTime.isTimeValid()) {&lt;br /&gt;
      Serial.println(&amp;quot;Failed to get time from server.&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
      Serial.printf(&amp;quot;Date Now is %s\n&amp;quot;, DateTime.toISOString().c_str());&lt;br /&gt;
      Serial.printf(&amp;quot;Timestamp is %lld\n&amp;quot;, DateTime.now());&lt;br /&gt;
    }&lt;br /&gt;
  #endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//SETUP&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
   //SERIAL&lt;br /&gt;
  Serial.begin(115200);         // Start the Serial communication to send messages to the computer&lt;br /&gt;
  delay(10);&lt;br /&gt;
  #ifdef SERIAL_DEBUG&lt;br /&gt;
    Serial.println(&amp;#039;\n&amp;#039;);&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  //WIFI&lt;br /&gt;
  WiFi.mode(WIFI_STA);// ist scheinbar der defaultwert wird in letzter Version nicht benutzt&lt;br /&gt;
  WiFi.begin(ssid, password);             // Connect to the network&lt;br /&gt;
  #ifdef SERIAL_DEBUG&lt;br /&gt;
    Serial.print(&amp;quot;Connecting to &amp;quot;);&lt;br /&gt;
    Serial.print(ssid); Serial.println(&amp;quot; ...&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    #ifdef SERIAL_DEBUG&lt;br /&gt;
      int i = 0;&lt;br /&gt;
      Serial.print(++i); Serial.print(&amp;quot;-&amp;gt;&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
  }&lt;br /&gt;
  mac=WiFi.macAddress();&lt;br /&gt;
  //clientId += String(random(0xffff), HEX);&lt;br /&gt;
  clientId = &amp;quot;ESP01-&amp;quot; + mac;&lt;br /&gt;
&lt;br /&gt;
  randomSeed(micros());&lt;br /&gt;
&lt;br /&gt;
  #ifdef SERIAL_DEBUG&lt;br /&gt;
    Serial.println(&amp;#039;\n&amp;#039;);&lt;br /&gt;
    Serial.println(&amp;quot;Connection established!&amp;quot;);&lt;br /&gt;
    Serial.print(&amp;quot;IP address:\t&amp;quot;);&lt;br /&gt;
    Serial.println(WiFi.localIP());         // Send the IP address of the ESP8266 to the computer&lt;br /&gt;
  #endif&lt;br /&gt;
&lt;br /&gt;
  //MQTT&lt;br /&gt;
  MQTTClient.setServer(MQTTServer, 1883);&lt;br /&gt;
  MQTTClient.setCallback(callback);&lt;br /&gt;
&lt;br /&gt;
  //DATETIME&lt;br /&gt;
  setupDateTime();&lt;br /&gt;
&lt;br /&gt;
  //TIMESETTING&lt;br /&gt;
  EEPROM.begin(sizeof(settings)); // 2 + 8 + 8 + 8&lt;br /&gt;
  boolean reliable1 = false, reliable2 = false;&lt;br /&gt;
  EEPROM.get(eepromAddr, settings); //read data from array in ram and cast it into struct called settings&lt;br /&gt;
  #ifdef MQTT_DEBUG_OUTPUT&lt;br /&gt;
    // in setup() MQTT isn&amp;#039;t connected so store the values and publish it in loop()&lt;br /&gt;
    snprintf (msgConfig, 50, &amp;quot;{EEPROMget:%c:%ld:%ld:%#lx}&amp;quot;,settings.mark,settings.timeActiveDir1,settings.timeActiveDir2,settings.checksum);&lt;br /&gt;
  #endif&lt;br /&gt;
  //if (strcmp(settings.mark,&amp;quot;#&amp;quot;) == 0){&lt;br /&gt;
  if (settings.mark == 35){&lt;br /&gt;
    crc.reset();&lt;br /&gt;
    crc.add(settings.timeActiveDir1);&lt;br /&gt;
    crc.add(settings.timeActiveDir2);&lt;br /&gt;
    if (crc.getCRC()==settings.checksum) reliable1 = true;&lt;br /&gt;
  }&lt;br /&gt;
  if (settings.timeActiveDir1 &amp;gt;= 50 &amp;amp;&amp;amp;     // values less than 50 ms  and greater than 24 hours are senseless&lt;br /&gt;
      settings.timeActiveDir1 &amp;lt;= 1440000 &amp;amp;&amp;amp;&lt;br /&gt;
      settings.timeActiveDir2 &amp;gt;= 50 &amp;amp;&amp;amp;&lt;br /&gt;
      settings.timeActiveDir2 &amp;lt;= 1440000) reliable2 = true;&lt;br /&gt;
&lt;br /&gt;
if (!(reliable1 &amp;amp;&amp;amp; reliable2)){ // if the Content of EEPROM is undefined, set it&lt;br /&gt;
  settings.mark = 35;&lt;br /&gt;
  settings.timeActiveDir1 = 180 * 1000; // default 3 minutes to switch off&lt;br /&gt;
  settings.timeActiveDir2 = 180 * 1000;&lt;br /&gt;
  crc.reset();&lt;br /&gt;
  crc.add(settings.timeActiveDir1);&lt;br /&gt;
  crc.add(settings.timeActiveDir2);&lt;br /&gt;
  settings.checksum=crc.getCRC();&lt;br /&gt;
  EEPROM.put(eepromAddr, settings); //write data structure to ram&lt;br /&gt;
  EEPROM.commit();  //write data from ram to flash memory. Do nothing if there are no changes to EEPROM data in ram&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  //RELAIS setup&lt;br /&gt;
  Serial.write(0); // initialize the uContoller that controls the relays&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// LOOP&lt;br /&gt;
void loop() {&lt;br /&gt;
&lt;br /&gt;
  if (!MQTTClient.connected()) {&lt;br /&gt;
    reconnect();&lt;br /&gt;
  }&lt;br /&gt;
  MQTTClient.loop();&lt;br /&gt;
&lt;br /&gt;
  // send out one time after setup&lt;br /&gt;
  if (!sendOutOneTime) {&lt;br /&gt;
    #ifdef MQTT_DEBUG_OUTPUT&lt;br /&gt;
      MQTTClient.publish(outRawTopic.c_str(), msgConfig);&lt;br /&gt;
      snprintf (msgConfig, 50, &amp;quot;{config:%c:%ld:%ld:%#lx}&amp;quot;,settings.mark,settings.timeActiveDir1,settings.timeActiveDir2,settings.checksum);&lt;br /&gt;
      MQTTClient.publish(outRawTopic.c_str(), msgConfig);&lt;br /&gt;
      sendOutOneTime = true;&lt;br /&gt;
    #endif&lt;br /&gt;
  }&lt;br /&gt;
  unsigned long now = millis();&lt;br /&gt;
&lt;br /&gt;
   if (now - lastMsg &amp;gt; ALIVEINTERVAL) {&lt;br /&gt;
     lastMsg = now;&lt;br /&gt;
     ++value;&lt;br /&gt;
     snprintf (msg, MQTT_MSG_BUFFER_SIZE, &amp;quot;%s&amp;quot;,DateTime.toISOString().c_str());&lt;br /&gt;
    #ifdef SERIAL_DEBUG&lt;br /&gt;
      Serial.print(&amp;quot;Publish message: &amp;quot;);&lt;br /&gt;
      Serial.println(msg);&lt;br /&gt;
    #endif&lt;br /&gt;
     MQTTClient.publish(outAliveTopic.c_str(), msg);&lt;br /&gt;
     snprintf (msg, MQTT_MSG_BUFFER_SIZE, &amp;quot;%d&amp;quot;,WiFi.RSSI());&lt;br /&gt;
    #ifdef SERIAL_DEBUG&lt;br /&gt;
      Serial.print(&amp;quot;Publish message: &amp;quot;);&lt;br /&gt;
      Serial.println(msg);&lt;br /&gt;
    #endif&lt;br /&gt;
     MQTTClient.publish(outRSSITopic.c_str(), msg);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   if ((now - startTimeDir1 &amp;gt; settings.timeActiveDir1) &amp;amp;&amp;amp; (startTimeDir1 != 0)){   // switch both relays to off after milliseconds defined in config (energy saving and safety aspects)&lt;br /&gt;
     #ifdef MQTT_DEBUG_OUTPUT&lt;br /&gt;
      snprintf (msg, MQTT_DEBUG_MSG_BUFFER_SIZE, &amp;quot;{Fallback1:%ld:%ld:%ld}&amp;quot;,now,startTimeDir1,settings.timeActiveDir1);&lt;br /&gt;
      MQTTClient.publish(outRawTopic.c_str(), msg);&lt;br /&gt;
    #endif&lt;br /&gt;
    sendRelaisCommand(2,false);&lt;br /&gt;
    delay(100);&lt;br /&gt;
    sendRelaisCommand(1,false);&lt;br /&gt;
    delay(500);&lt;br /&gt;
    startTimeDir1 = 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if ((now - startTimeDir2 &amp;gt; settings.timeActiveDir2) &amp;amp;&amp;amp; (startTimeDir2 != 0)){    // switch both relays to off after milliseconds defined in config (energy saving and safety aspects)&lt;br /&gt;
     #ifdef MQTT_DEBUG_OUTPUT&lt;br /&gt;
      snprintf (msg, MQTT_DEBUG_MSG_BUFFER_SIZE, &amp;quot;{Fallback2:%ld:%ld:%ld}&amp;quot;,now,startTimeDir2,settings.timeActiveDir2);&lt;br /&gt;
      MQTTClient.publish(outRawTopic.c_str(), msg);&lt;br /&gt;
    #endif&lt;br /&gt;
    sendRelaisCommand(2,false);&lt;br /&gt;
    delay(100);&lt;br /&gt;
    sendRelaisCommand(1,false);&lt;br /&gt;
    delay(500);&lt;br /&gt;
    startTimeDir2 = 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Chris T. Ludwig</name></author>
	</entry>
</feed>