<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de"><title>Tobias Schulz</title><subtitle>Smart Home, Technik, Kram</subtitle><id>https://tbsch.de/</id><updated>2026-06-10T00:00:00Z</updated><author><name>Tobias Schulz</name></author><rights>2022 - 2026 Tobias Schulz</rights><generator uri="https://gohugo.io/">Hugo</generator><link href="https://tbsch.de/" rel="alternate" type="text/html"/><link href="https://tbsch.de/atom.xml" rel="self" type="application/atom+xml"/><entry><title>Vater werden - und was das mit allem macht</title><link href="https://tbsch.de/post/2026-06-10-vater-werden-und-was-das-mit-allem-macht/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2026-06-10-vater-werden-und-was-das-mit-allem-macht/</id><published>2026-06-10T00:00:00Z</published><updated>2026-06-10T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="meinung"/><category term="familie"/><category term="gewohnheit"/><category term="bericht"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2026-06-10-vater-werden-und-was-das-mit-allem-macht/featured.webp"/><summary type="html">Ein Kind krempelt nicht nur den Schlaf um, sondern auch Selbstbild, Hobbys und Freundschaften.</summary><content type="html">&lt;div class="lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl"&gt;
Ich dachte, ich hätte mein Leben ganz gut im Griff. Dann kam ein winziger Mensch und hat mir liebevoll das Gegenteil bewiesen.
&lt;/div&gt;
&lt;p&gt;Es ist kurz vor vier Uhr morgens. Ich stehe im abgedunkelten Kinderzimmer, wiege ein winziges, warmes Bündel Mensch im Arm und bin müde und überglücklich zugleich. Für den Bruchteil einer Sekunde meldet sich der alte Nerd in mir und fragt, ob man diese Nachtschichten nicht irgendwie eleganter lösen könnte - dann lache ich leise über mich selbst &amp;#x1f601;. Manche Dinge löst man eben nicht. Man ist einfach da.&lt;/p&gt;
&lt;p&gt;Unter dem müden Papa im Halbdunkel steckt nämlich nach wie vor ein Kontrollmensch. Pläne geben mir Ruhe, ein durchdachter Ablauf fühlt sich für mich nach Komfort an und nicht nach Zwang.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Der Reset, den ich nicht eingeplant hatte
&lt;div id="der-reset-den-ich-nicht-eingeplant-hatte" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#der-reset-den-ich-nicht-eingeplant-hatte" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Und dann bekommst du ein Kind, und dieses Kind schert sich &lt;strong&gt;null&lt;/strong&gt; um deine schönen Pläne. Es kennt keine Uhrzeit, es kennt keinen Wochentag, und es fragt dich nicht, ob es gerade passt. Es meldet sich um 3:47 Uhr, und die einzig richtige Antwort darauf ist: da sein. Sofort, und ohne zu überlegen.&lt;/p&gt;
&lt;p&gt;Für mich war das anfangs ungewohnt. Ich konnte nichts vorbereiten, nichts vorausplanen, nichts beschleunigen. Ich musste einfach präsent sein - und das war, ehrlich gesagt, ein bislang verborgenes Talent in mir &amp;#x1f605;. Ich wusste bisher nicht, dass ich dermaßen gut im Improvisieren bin. Nicht alles im Leben muss sich rechnen, manches darf einfach Chaos sein. Wer hätte gedacht, dass mir das ausgerechnet ein paar schlaflose Nächte beibringen.&lt;/p&gt;
&lt;p&gt;Die ersten zwei Wochen nach der Geburt verschwimmen im Rückblick zu einem einzigen, sehr müden Nebel. Schlaf gab es nur noch häppchenweise, immer dann, wenn der kleine Mensch es gerade zuließ, nie am Stück. Und in den ersten vier Wochen war ich eigentlich nur noch am Laufen: hier schnell etwas organisieren, da der Haushalt, dazwischen ein paar Besorgungen, und natürlich immer Mama und Kind versorgen. Stillstand? Fehlanzeige. Ein gern gesehener Gast in dieser Zeit hieß übrigens &lt;em&gt;Lieferando&lt;/em&gt; - Kochen stand schlicht nicht auf der Liste der Dinge, für die noch Energie übrig war &amp;#x1f648;.&lt;/p&gt;
&lt;p&gt;Und dann passiert etwas Erstaunliches: Nach vier, fünf Wochen pendelt sich ein neuer Rhythmus ein. Nicht meiner, nicht der alte - ein komplett neuer, den wir zu dritt erst zusammen erfinden mussten. Verglichen mit diesem ersten Sturm ist der Alltag mit Kind heute ein &lt;strong&gt;Klacks&lt;/strong&gt;. Damals, mitten im Nebel, hätte ich das nicht für möglich gehalten.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Was es mit dem Nerd macht
&lt;div id="was-es-mit-dem-nerd-macht" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-es-mit-dem-nerd-macht" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Ich bin immer noch ein Nerd. Das bleibt auch so, da müssen alle durch. Aber die Währung hat sich geändert.&lt;/p&gt;
&lt;p&gt;Früher war Zeit für Hobbys einfach da. Ein Abend mit Python, ein Wochenende mit einem neuen Projekt, kein Thema. Heute messe ich Hobby-Zeit in &lt;strong&gt;Minuten&lt;/strong&gt;, und ich gebe sie sehr viel bewusster aus. Das klingt erst mal nach Verlust - ist es aber nicht. Selbst Apple könnte so einen effektiven Fokus-Filter nicht entwickeln: Wenn ich nur noch eine halbe Stunde habe, mache ich garantiert nicht den Quatsch, der mir eigentlich egal ist. Du kennst das sicher auch: schnell mal einen neuen Docker Container ausprobieren und zack, ist der Abend schon wieder rum. Für solche Themen nutze ich in letzter Zeit sehr stark die Möglichkeiten von KI; mal eben schnell nebenbei.&lt;/p&gt;
&lt;p&gt;Selbst mein Smart Home ist mit Kind nicht komplizierter geworden, sondern ehrlicher: Was nur Spielerei war, nervt im Alltag sofort und fliegt, der Rest darf bleiben.&lt;/p&gt;
&lt;p&gt;Was mir übrigens am meisten hilft, hat ausnahmsweise mal nur indirekt mit Technik zu tun: Ich arbeite im Homeoffice. Früher hielt ich das für einen netten Komfort-Bonus, heute ist es für mich schlicht &lt;strong&gt;unbezahlbar&lt;/strong&gt;. Ich bin bei den kleinen und großen, wichtigen Momenten dabei - beim ersten echten Lachen, bei der ersten Seitwärtsdrehung, beim Mittagsschlaf auf meiner Brust, beim Quengeln, das partout nur auf dem Papa-Arm wieder aufhört. Dafür bin ich meinem Arbeitgeber sehr dankbar. Längst nicht jeder Berufstätige in Vollzeit hat dieses Privileg, und ich vergesse das keine Sekunde.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Was es mit dem Umfeld macht
&lt;div id="was-es-mit-dem-umfeld-macht" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-es-mit-dem-umfeld-macht" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Eine Sache, die mir vorher niemand so deutlich gesagt hat: Ein Kind sortiert ganz nebenbei dein Umfeld. Nicht immer mit großem Knall - einfach dadurch, dass dein Alltag enger getaktet wird und du auf einmal sehr genau merkst, für wen darin noch Platz ist.&lt;/p&gt;
&lt;p&gt;Am Anfang passiert sogar das Gegenteil von Sortieren. Du lernst plötzlich andere frischgebackene Eltern kennen, und durch den geteilten Schlafentzug fühlt sich das in Windeseile nach tiefer Freundschaft an. Man schreibt sich nachts um drei, weil beide ohnehin wach sind, man teilt die kleinen Katastrophen und die großen Glücksmomente. Diese Nähe ist echt - aber sie entsteht eben unter Ausnahmebedingungen. Und was im Ausnahmezustand zusammenwächst, hält dem normalen Alltag nicht immer stand. Manche dieser intensiven Anfangsfreundschaften werden wieder leiser, sobald sich der erste Sturm legt. Das tut kurz weh, ist aber völlig normal.&lt;/p&gt;
&lt;p&gt;Gleichzeitig verschieben sich die alten Beziehungen. Freunde ohne Kinder leben in einem anderen Takt; du sagst öfter ab, als dir lieb ist, und irgendwann lädt man dich gar nicht mehr spontan ein. Das ist selten böse gemeint, es ist einfach das Auseinanderdriften zweier Lebensphasen. Dafür werden andere Verbindungen unerwartet eng - oft genau die, von denen du es am wenigsten gedacht hättest.&lt;/p&gt;
&lt;p&gt;Und dann gibt es da die Menschen, die in den ersten Wochen einfach &lt;strong&gt;da&lt;/strong&gt; waren - ganz praktisch und bedingungslos. Freunde und Familie, die mit Essen vor der Tür standen oder sogar einen vorgekochten Topf dalassen, schnell den Müll rausbrachten oder im Vorbeigehen eine Maschine Wäsche anwarfen, während wir beide am absoluten Limit liefen. Niemand schreibt dir vorher ins Lehrbuch, wie kostbar eine warme Mahlzeit ist, die du nicht selbst kochen musstest.&lt;/p&gt;
&lt;p&gt;Was am Ende bleibt, ist eine ziemlich eindeutige Antwort auf eine Frage, die man sich vorher nie so direkt stellt: Wer taucht eigentlich auf, wenn es gerade &lt;em&gt;nicht&lt;/em&gt; bequem ist? Wer schreibt nicht nur &amp;ldquo;meld dich, wenn ihr was braucht&amp;rdquo;, sondern steht mit einer Tüte Einkäufe vor der Tür, ohne vorher zu fragen? Diese Liste ist kürzer, als ich dachte. Aber jede Person darauf hat ihren Platz in unserem Herzen mehr als verdient.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Der neue Maßstab
&lt;div id="der-neue-maßstab" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#der-neue-ma%c3%9fstab" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Vater zu werden hat nicht eine einzelne Sache in meinem Leben verändert, sondern den Maßstab für alle. Routinen, Selbstbild, Hobbys - alles misst sich heute an derselben, sehr einfachen Frage: &lt;strong&gt;Ist mir das die Zeit wert, die ich stattdessen mit meiner Familie haben könnte?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Der Mensch in mir, der immer alles im Griff haben will, hat dabei das Schwerste gelernt, was es für ihn gibt: loslassen. Nicht alles muss durchdacht und durchgeplant sein. Manches muss einfach nur &lt;strong&gt;da&lt;/strong&gt; sein. Pure Aufregung, pures Chaos - und ich würde keine Sekunde davon zurückgeben &amp;#x1f60e;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@fagin?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Marcel Fagin &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/baby-mit-weisser-decke-bedeckt-OUYg0Q3ec-Y?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Node-RED Topic Mapper für Zendure SolarFlow</title><link href="https://tbsch.de/post/2026-06-03-node-red-topic-mapper-f%C3%BCr-zendure-solarflow/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2026-06-03-node-red-topic-mapper-f%C3%BCr-zendure-solarflow/</id><published>2026-06-03T00:00:00Z</published><updated>2026-06-03T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="smart-home"/><category term="guide"/><category term="home-assistant"/><category term="mqtt"/><category term="node-red"/><category term="zendure"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2026-06-03-node-red-topic-mapper-f%C3%BCr-zendure-solarflow/featured.webp"/><summary type="html">Ein Node-RED-Flow, der Zendure-MQTT-Topics in ein sauberes Schema für Home Assistant bringt.</summary><content type="html">&lt;div class="lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl"&gt;
Ein kleiner Node-RED-Flow, der die Zendure-MQTT-Topics in ein verwertbares Schema für &lt;em&gt;Home Assistant&lt;/em&gt; überführt. Robust und ohne weiteren Docker-Container.
&lt;/div&gt;
&lt;p&gt;Im &lt;a href="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/"&gt;Beitrag zur lokalen Anbindung&lt;/a&gt; hatte ich den Topic-Mapper-Flow noch nicht teilen können, weil er zu sehr auf meine Installation zugeschnitten war. Inzwischen ist er aufgeräumt, hostnamenfrei und seit Monaten produktiv. Höchste Zeit, den Flow rauszugeben &amp;#x1f601;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Warum der Mapper überhaupt nötig ist
&lt;div id="warum-der-mapper-überhaupt-nötig-ist" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#warum-der-mapper-%c3%bcberhaupt-n%c3%b6tig-ist" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wenn dein &lt;a href="https://amzlink.to/az02JNcHey1gW" target="_blank" rel="noopener noreferrer"&gt;SolarFlow &lt;i class="ti ti-shopping-cart-share" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; lokal über MQTT spricht (das hardcoded Passwort errechnest du &lt;a href="/post/2025-06-30-zendure-solarflow-mqtt-passwort-knacken/"&gt;hier&lt;/a&gt;), bekommst du Topics in dieser Form:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;Inhalt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/+/+/properties/report&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Properties des Hubs und &lt;code&gt;packData&lt;/code&gt; der Akkus.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/+/+/properties/write/reply&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Antworten auf Schreibbefehle, gleicher Payload-Stil.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/+/+/log&lt;/code&gt; und &lt;code&gt;/+/+/event&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Geräte-Logs und sonstige Events.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Die eigentlichen Messwerte stecken &lt;strong&gt;alle in einem einzigen &lt;code&gt;properties&lt;/code&gt;-Objekt&lt;/strong&gt; und kommen nur als &lt;strong&gt;Delta&lt;/strong&gt;: ändert sich &lt;code&gt;solarInputPower&lt;/code&gt;, kommt eine Nachricht mit ausschließlich diesem Schlüssel. Für saubere MQTT-Sensoren in &lt;em&gt;Home Assistant&lt;/em&gt; ist das ungeeignet, denn dort braucht jeder Sensor &lt;strong&gt;genau ein Topic&lt;/strong&gt; mit einem &lt;strong&gt;stabilen, retained Wert&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Genau diese Lücke schließt der Mapper. Er zerlegt jedes &lt;code&gt;properties&lt;/code&gt;-Objekt in einzelne Topics, baut für &lt;code&gt;packData&lt;/code&gt; einen Akku-Baum, hält den Online-Status nach, und bietet als Bonus einen sauberen Befehls-Eingang.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Für genau dieses Mapping gibt es ein Python-Skript im Original-Repo des &lt;strong&gt;SolarFlow Bluetooth Managers&lt;/strong&gt;: &lt;a href="https://github.com/reinhard-brandstaedter/solarflow-bt-manager/blob/master/src/solarflow-topic-mapper.py" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;solarflow-topic-mapper.py&lt;/code&gt; &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;. Sehr ordentliche Vorlage, die letzte Code-Änderung liegt allerdings rund zwei Jahre zurück. Vor allem aber wollte ich keinen weiteren Docker-Container für eine Aufgabe, die &lt;em&gt;Node-RED&lt;/em&gt; einfach direkt miterledigen kann.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Zielschema
&lt;div id="zielschema" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#zielschema" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Aus dem Wust an Zendure-Topics soll am Ende dieses Schema rauskommen, alles retained:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;Bedeutung&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zendure/&amp;lt;device_id&amp;gt;/telemetry/&amp;lt;key&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ein Topic pro Property&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zendure/&amp;lt;device_id&amp;gt;/batteries/&amp;lt;sn&amp;gt;/&amp;lt;prop&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ein Topic pro Pack-Property pro Akku&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zendure/&amp;lt;device_id&amp;gt;/status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;quot;online&amp;quot;&lt;/code&gt; als Lebenszeichen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zendure/cmd/&amp;lt;product&amp;gt;/&amp;lt;id&amp;gt;/properties/write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;sauberer Befehls-Eingang&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Der letzte Punkt ist der Komfort-Bonus: Befehle auf &lt;code&gt;zendure/cmd/...&lt;/code&gt; werden vom Mapper transparent auf das Zendure-interne &lt;code&gt;iot/...&lt;/code&gt; umgeschrieben. Aus Sicht der Automations-Schicht gibt es nur noch einen einzigen Namespace &lt;code&gt;zendure/&lt;/code&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Architektur
&lt;div id="architektur" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#architektur" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;pre class="not-prose mermaid"&gt;
flowchart TD
sf["Zendure&lt;br/&gt;SolarFlow"]
broker["MQTT-Broker"]
parse["parse telemetry"]
settopic["set topic"]
rewrite["rewrite topic"]
ha["Home Assistant"]
sf --&gt;|"/+/+/properties/report&lt;br&gt;/+/+/properties/write/reply"| parse
sf --&gt;|"/+/+/log&lt;br&gt;/+/+/event"| settopic
parse --&gt;|"zendure/__id__/..."| broker
settopic --&gt;|"zendure/__id__/status"| broker
broker --&gt; ha
ha --&gt;|"zendure/cmd/..."| rewrite
rewrite --&gt;|"iot/..."| sf
&lt;/pre&gt;
&lt;h2 class="relative group"&gt;Function Node
&lt;div id="function-node" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#function-node" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Die wichtigste Function. Sie zerlegt &lt;code&gt;properties&lt;/code&gt; und &lt;code&gt;packData&lt;/code&gt; und setzt nebenbei den Online-Status:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;topic_parts&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;topic&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;device_id&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;topic_parts&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;is_write_reply&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;write&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;reply&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;every&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;part&lt;/span&gt; =&amp;gt; &lt;span style="color:#a6e22e"&gt;topic_parts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;includes&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;part&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;has_properties&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;has_pack_data&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;is_write_reply&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;has_properties&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;properties&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;([{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;topic&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`zendure/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;device_id&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/telemetry/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;properties&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;retain&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#34;packData&amp;#34;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; Array.&lt;span style="color:#a6e22e"&gt;isArray&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;packData&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;has_pack_data&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;packData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;pack&lt;/span&gt; =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sn&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pack&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sn&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;delete&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pack&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sn&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;prop&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pack&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;([{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;topic&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`zendure/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;device_id&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/batteries/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;sn&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;prop&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pack&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;prop&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;retain&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;has_properties&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;has_pack_data&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;([&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;([&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;topic&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`zendure/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;device_id&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/status`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;online&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;retain&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}]);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Drei Outputs: &lt;strong&gt;telemetry&lt;/strong&gt; (verbunden mit MQTT-Out), &lt;strong&gt;others&lt;/strong&gt; (für Debug-Zwecke offen) und &lt;strong&gt;status&lt;/strong&gt;. Die &lt;code&gt;write/reply&lt;/code&gt;-Antworten werden bewusst nicht als Telemetrie ausgewertet, weil ihr Payload nur das wiedergibt, was ich selbst gerade geschrieben habe. Sie zählen aber als Lebenszeichen. Das Topic-Ziel enthält absichtlich nur die &lt;code&gt;device_id&lt;/code&gt;, nicht die &lt;code&gt;product_id&lt;/code&gt;, was die Sensor-Konfiguration in &lt;em&gt;Home Assistant&lt;/em&gt; einfacher hält.&lt;/p&gt;
&lt;p&gt;Die beiden anderen Functions sind Einzeiler. &lt;code&gt;set topic&lt;/code&gt; setzt für &lt;code&gt;log&lt;/code&gt; und &lt;code&gt;event&lt;/code&gt; nur den Status &lt;code&gt;&amp;quot;online&amp;quot;&lt;/code&gt; auf &lt;code&gt;zendure/&amp;lt;device_id&amp;gt;/status&lt;/code&gt;. &lt;code&gt;rewrite topic&lt;/code&gt; ersetzt für den Befehls-Kanal das Präfix &lt;code&gt;zendure/cmd/&lt;/code&gt; durch &lt;code&gt;iot/&lt;/code&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Den Flow importieren
&lt;div id="den-flow-importieren" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#den-flow-importieren" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;In &lt;em&gt;Node-RED&lt;/em&gt; über &lt;strong&gt;Menü → Import&lt;/strong&gt; in einen leeren Tab einfügen. Vor dem Deploy zwei Dinge anpassen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;MQTT-Broker.&lt;/strong&gt; Im Knoten &lt;code&gt;Home Assistant MQTT&lt;/code&gt; Hostname, Port, Zugangsdaten und TLS-Optionen auf deine Umgebung umstellen. Im Beispiel steht ein Platzhalter &lt;code&gt;mqtt-broker.local&lt;/code&gt; mit Port &lt;code&gt;8883&lt;/code&gt; und aktivem TLS.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TLS-Zertifikate.&lt;/strong&gt; Wenn dein Broker keine Client-Zertifikate verlangt, die TLS-Config leeren oder den TLS-Block entfernen. &lt;code&gt;verifyservercert: false&lt;/code&gt; ist auf meine eigene CA gemünzt, prüfe das bei dir.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;tab&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;label&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;Zendure SolarFlow Topic Mapper&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;disabled&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;info&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;env&amp;#34;&lt;/span&gt;:[]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;dbef3a2a6ac13d38&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;group&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;Zendure Telemetry Topics verarbeiten&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;style&amp;#34;&lt;/span&gt;:{&lt;span style="color:#f92672"&gt;&amp;#34;label&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;color&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;#999999&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;fill&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;#ffefbf&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;fill-opacity&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0.2&amp;#34;&lt;/span&gt;},&lt;span style="color:#f92672"&gt;&amp;#34;nodes&amp;#34;&lt;/span&gt;:[&lt;span style="color:#e6db74"&gt;&amp;#34;70239655f64ff049&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;c4294b73f2df7591&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;3ed191421ad7509e&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;990c5574211cdd6a&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;b9f7cc71f1ea571f&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;ab5f182a4c5df576&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;48153921e53c4182&amp;#34;&lt;/span&gt;],&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;14&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;119&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;612&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;h&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;202&lt;/span&gt;},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;db3fb2bbd94f8068&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;group&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;MQTT Befehle an Zendure Broker&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;style&amp;#34;&lt;/span&gt;:{&lt;span style="color:#f92672"&gt;&amp;#34;label&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;fill&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;#ffbfbf&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;fill-opacity&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0.2&amp;#34;&lt;/span&gt;},&lt;span style="color:#f92672"&gt;&amp;#34;nodes&amp;#34;&lt;/span&gt;:[&lt;span style="color:#e6db74"&gt;&amp;#34;3065a73c7cb7203b&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;a08d74f99a34b6c9&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;c065eba5601fb19a&amp;#34;&lt;/span&gt;],&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;54&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;379&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;492&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;h&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;82&lt;/span&gt;},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;70239655f64ff049&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;function&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;dbef3a2a6ac13d38&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;parse telemetry&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;func&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;const topic_parts = msg.topic.split(\&amp;#34;/\&amp;#34;);\nconst product_id = topic_parts[1];\nconst device_id = topic_parts[2];\nconst is_write_reply = [\&amp;#34;write\&amp;#34;, \&amp;#34;reply\&amp;#34;].every(part =&amp;gt; topic_parts.includes(part));\nlet has_properties = false;\nlet has_pack_data = false;\nif (\&amp;#34;properties\&amp;#34; in msg.payload &amp;amp;&amp;amp; !is_write_reply) {\n has_properties = true;\n for (let key in msg.payload.properties) {\n node.send([{ topic: `zendure/${device_id}/telemetry/${key}`, payload: msg.payload.properties[key], retain: true }, null, null]);\n }\n}\nif (\&amp;#34;packData\&amp;#34; in msg.payload &amp;amp;&amp;amp; Array.isArray(msg.payload.packData)) {\n has_pack_data = true;\n msg.payload.packData.forEach(pack =&amp;gt; {\n const sn = pack.sn;\n delete pack.sn;\n for (let prop in pack) {\n node.send([{ topic: `zendure/${device_id}/batteries/${sn}/${prop}`, payload: pack[prop], retain: true }, null, null]);\n }\n });\n}\nif (!has_properties &amp;amp;&amp;amp; !has_pack_data) node.send([null, msg, null]);\nnode.send([null, null, { topic: `zendure/${device_id}/status`, payload: \&amp;#34;online\&amp;#34;, retain: true }]);&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;outputs&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;timeout&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;noerr&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;initialize&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;finalize&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;libs&amp;#34;&lt;/span&gt;:[],&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;360&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;180&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[[&lt;span style="color:#e6db74"&gt;&amp;#34;c4294b73f2df7591&amp;#34;&lt;/span&gt;],[],[]],&lt;span style="color:#f92672"&gt;&amp;#34;outputLabels&amp;#34;&lt;/span&gt;:[&lt;span style="color:#e6db74"&gt;&amp;#34;telemetry&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;others&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;c4294b73f2df7591&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt out&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;dbef3a2a6ac13d38&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt out&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;qos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;retain&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;respTopic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;contentType&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;userProps&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;correl&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;expiry&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;broker&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;666dbb21de861090&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;540&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;180&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;3ed191421ad7509e&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt in&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;dbef3a2a6ac13d38&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;sf properties/report&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;/+/+/properties/report&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;qos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;datatype&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;auto-detect&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;broker&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;666dbb21de861090&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;nl&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rap&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rh&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;inputs&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;130&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;160&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[[&lt;span style="color:#e6db74"&gt;&amp;#34;70239655f64ff049&amp;#34;&lt;/span&gt;]]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;990c5574211cdd6a&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt in&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;dbef3a2a6ac13d38&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;sf log&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;/+/+/log&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;qos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;datatype&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;auto-detect&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;broker&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;666dbb21de861090&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;nl&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rap&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rh&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;inputs&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;90&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;240&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[[&lt;span style="color:#e6db74"&gt;&amp;#34;ab5f182a4c5df576&amp;#34;&lt;/span&gt;]]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;b9f7cc71f1ea571f&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt in&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;dbef3a2a6ac13d38&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;sf event&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;/+/+/event&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;qos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;datatype&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;auto-detect&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;broker&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;666dbb21de861090&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;nl&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rap&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rh&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;inputs&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;90&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;280&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[[&lt;span style="color:#e6db74"&gt;&amp;#34;ab5f182a4c5df576&amp;#34;&lt;/span&gt;]]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;ab5f182a4c5df576&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;function&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;dbef3a2a6ac13d38&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;set topic&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;func&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;const topic_parts = msg.topic.split(\&amp;#34;/\&amp;#34;);\nconst device_id = topic_parts[2];\nmsg.topic = `zendure/${device_id}/status`;\nmsg.payload = \&amp;#34;online\&amp;#34;;\nmsg.retain = true;\nreturn msg;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;outputs&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;timeout&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;noerr&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;initialize&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;finalize&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;libs&amp;#34;&lt;/span&gt;:[],&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;360&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;240&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[[]]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;48153921e53c4182&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt in&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;dbef3a2a6ac13d38&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;sf properties/write/reply&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;/+/+/properties/write/reply&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;qos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;datatype&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;auto-detect&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;broker&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;666dbb21de861090&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;nl&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rap&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rh&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;inputs&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;140&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[[&lt;span style="color:#e6db74"&gt;&amp;#34;70239655f64ff049&amp;#34;&lt;/span&gt;]]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;3065a73c7cb7203b&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt in&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;db3fb2bbd94f8068&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt in&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;zendure/cmd/#&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;qos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;datatype&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;auto-detect&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;broker&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;666dbb21de861090&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;nl&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rap&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;rh&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;2&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;inputs&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;130&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;420&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[[&lt;span style="color:#e6db74"&gt;&amp;#34;a08d74f99a34b6c9&amp;#34;&lt;/span&gt;]]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;a08d74f99a34b6c9&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;function&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;db3fb2bbd94f8068&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;rewrite topic&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;func&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;msg.topic = msg.topic.replace(\&amp;#34;zendure/cmd/\&amp;#34;, \&amp;#34;iot/\&amp;#34;);\nreturn msg;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;outputs&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;timeout&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;noerr&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;initialize&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;finalize&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;libs&amp;#34;&lt;/span&gt;:[],&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;290&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;420&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[[&lt;span style="color:#e6db74"&gt;&amp;#34;c065eba5601fb19a&amp;#34;&lt;/span&gt;]]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;c065eba5601fb19a&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt out&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;661870a4a8dc9578&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;g&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;db3fb2bbd94f8068&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt out&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;qos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;retain&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;respTopic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;contentType&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;userProps&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;correl&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;expiry&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;broker&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;666dbb21de861090&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;460&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;420&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;wires&amp;#34;&lt;/span&gt;:[]},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;666dbb21de861090&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt-broker&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;Home Assistant MQTT&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;broker&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt-broker.local&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;port&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;8883&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;1c39c6626d1e78ba&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;clientid&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;node-red&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;autoConnect&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;usetls&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;protocolVersion&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;5&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;keepalive&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;60&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;cleansession&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;autoUnsubscribe&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;birthTopic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;birthQos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;birthRetain&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;false&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;birthPayload&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;birthMsg&amp;#34;&lt;/span&gt;:{},&lt;span style="color:#f92672"&gt;&amp;#34;closeTopic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;closeQos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;closeRetain&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;false&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;closePayload&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;closeMsg&amp;#34;&lt;/span&gt;:{},&lt;span style="color:#f92672"&gt;&amp;#34;willTopic&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;willQos&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;willRetain&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;false&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;willPayload&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;willMsg&amp;#34;&lt;/span&gt;:{},&lt;span style="color:#f92672"&gt;&amp;#34;userProps&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;sessionExpiry&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;},{&lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;1c39c6626d1e78ba&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;tls-config&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt CA&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;cert&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;ca&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;certname&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;client.crt&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;keyname&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;client.key&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;caname&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;ca.crt&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;servername&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt-broker.local&amp;#34;&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;verifyservercert&amp;#34;&lt;/span&gt;:&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,&lt;span style="color:#f92672"&gt;&amp;#34;alpnprotocol&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;}]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Property-Namen wandern 1:1 ins Topic (&lt;code&gt;solarInputPower&lt;/code&gt;, &lt;code&gt;electricLevel&lt;/code&gt;, &lt;code&gt;outputPackPower&lt;/code&gt;, &amp;hellip;). Eine vollständige Auflistung pflegt Zendure selbst im &lt;a href="https://github.com/Zendure/developer-device-data-report?tab=readme-ov-file#solarflow" target="_blank" rel="noopener noreferrer"&gt;Developer-Repo &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Der Mapper läuft bei mir seit Monaten unauffällig. Ein Stück Infrastruktur, das du einmal baust und dann vergisst - genau so soll es sein &amp;#x1f604;.&lt;/p&gt;
&lt;p&gt;Viel Spaß beim Importieren &amp;#x1f60e;!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@purzlbaum?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Claudio Schwarz &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/nahaufnahme-eines-fensters-mit-einem-gebaude-im-hintergrund-fyeOxvYvIyY?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Interaktiver Reinigungsplan mit Home Assistant</title><link href="https://tbsch.de/post/2026-05-31-interaktiver-reinigungsplan-mit-home-assistant/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2026-05-31-interaktiver-reinigungsplan-mit-home-assistant/</id><published>2026-05-31T00:00:00Z</published><updated>2026-05-31T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="smart-home"/><category term="guide"/><category term="haushalt"/><category term="home-assistant"/><category term="workflow"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2026-05-31-interaktiver-reinigungsplan-mit-home-assistant/featured.webp"/><summary type="html">Local calendar, To-do list und Roborock zu einem Reinigungsplan kombiniert, der sich selbst pflegt.</summary><content type="html">&lt;div class="lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl"&gt;
Ein guter Reinigungsplan plant sich selbst - du musst ihn nur einmal vernünftig aufschreiben.
&lt;/div&gt;
&lt;p&gt;Erinnerst du dich noch an mein Versprechen vom Ende des &lt;a href="/post/2024-09-25-aktivierung-von-home-assistant-szenen-verfolgen-part-2/"&gt;Scene-History Beitrags&lt;/a&gt;? Ich mich schon: denn ich hatte angekündigt, dass ich darüber schreibe, wie ich mit &lt;em&gt;Local calendar&lt;/em&gt;, &lt;em&gt;To-do list&lt;/em&gt; und &lt;em&gt;Roborock&lt;/em&gt; einen &lt;strong&gt;interaktiven Reinigungsplan&lt;/strong&gt; in &lt;em&gt;Home Assistant&lt;/em&gt; gebaut habe. Das ist jetzt knapp zwei Jahre her, höchste Zeit also &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;Vorab eine ehrliche Ansage: das hier ist kein One-Click-Setup. Wir bauen mehrere Bausteine zusammen, jeder davon einzeln nicht weltbewegend, in Kombination aber überraschend mächtig. Wer schon Lust hat, kann sich die Reihenfolge gleich merken: &lt;strong&gt;Kalender&lt;/strong&gt; als Plan, &lt;strong&gt;Template Sensor&lt;/strong&gt; als heutige Wahrheit, &lt;strong&gt;Script&lt;/strong&gt; für die eigentliche Reinigung, &lt;strong&gt;Todo-Liste&lt;/strong&gt; als Statusanzeige für die Familie und &lt;strong&gt;zwei Automationen&lt;/strong&gt; als Klebstoff.&lt;/p&gt;
&lt;p&gt;Klingt nach Aufwand? Ist es auch. Klingt nach Spaß? Definitiv &amp;#x1f60e;.&lt;/p&gt;
&lt;p&gt;Insgesamt sind es &lt;strong&gt;drei Automationen&lt;/strong&gt;, die wir bauen: eine, die saugt, eine, die nachts die Status-Liste neu aufbaut, und eine, die nach dem Saugen die heute fälligen Räume in der Liste abhakt. Klingt nach viel, ist aber jede für sich kurz und folgt einer klaren Aufgabe.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Anforderungen an den Plan
&lt;div id="anforderungen-an-den-plan" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#anforderungen-an-den-plan" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Bevor ich angefangen habe, wollte ich für mich klären, was der Plan eigentlich können soll. Ohne klare Anforderung baust du sonst monatelang am Symptom statt an der Ursache. Mein Anspruch war konkret folgender:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pro Raum eigener Rhythmus.&lt;/strong&gt; Wohnzimmer und Flur fast täglich, Schlafzimmer zwei- bis dreimal die Woche, andere Räume nach Bedarf.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wiederholungen pro Tag möglich.&lt;/strong&gt; Manche Tage rechtfertigen einen zweiten Durchlauf, andere nicht. Soll der Plan steuern, nicht ich.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nur, wenn niemand stört.&lt;/strong&gt; Kein Roborock, wenn das Kind schläft, der Fernseher läuft oder jemand in der betroffenen Etage arbeitet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Selbst-pflegende Status-Anzeige.&lt;/strong&gt; Damit meine Frau und ich auf einen Blick sehen, was heute ansteht und was bereits erledigt ist - ganz ohne, dass jemand etwas händisch eintragen muss.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Mein Setup besteht aus genau &lt;strong&gt;einem&lt;/strong&gt; &lt;a href="https://amzlink.to/az0YfePSum1uy" target="_blank" rel="noopener noreferrer"&gt;Roborock S7 &lt;i class="ti ti-shopping-cart-share" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;, der über &lt;em&gt;Segment Cleaning&lt;/em&gt; gezielt einzelne Räume anfährt. Wenn du mehrere Sauger oder gar mehrere Stockwerke hast, lassen sich die Bausteine erweitern - das Grundprinzip bleibt aber identisch.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Die Bausteine im Überblick
&lt;div id="die-bausteine-im-überblick" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#die-bausteine-im-%c3%bcberblick" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Bevor ich in die Konfiguration einsteige, kurz die Architektur. Das hilft dir später, dich im Code zurechtzufinden:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Baustein&lt;/th&gt;
&lt;th style="text-align: left"&gt;Aufgabe&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;calendar.auto_vacuum&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Hält den Plan: welcher Raum, wie oft, in welchem Zeitfenster.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;binary_sensor.auto_vacuum_schedule&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Liest den Kalender und berechnet &lt;strong&gt;heute&lt;/strong&gt; und &lt;strong&gt;als Nächstes&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;script.turn_on_vacuum_segment_cleaning&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Übersetzt &lt;em&gt;Home Assistant&lt;/em&gt; Areas in Roborock-Segmente und löst die Reinigung aus.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;todo.auto_vacuum&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Status-Anzeige fürs Dashboard mit Fälligkeitsdatum pro Raum.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;automation.staubsauger_starten&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Klebstoff: triggert bei passender Gelegenheit, prüft Bedingungen, ruft das Script auf.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;automation.staubsauger_todos_bauen&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Pflegt nachts die Todo-Liste neu, damit Fälligkeiten stimmen.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;automation.staubsauger_todos_abhaken&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Hakt die heute fälligen Items nach erfolgreicher Reinigung in der Todo-Liste ab.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Es lohnt sich, das einmal vor sich hinzuzeichnen. &lt;strong&gt;Stichwort:&lt;/strong&gt; &lt;em&gt;Skizze schlägt Schreibtisch&lt;/em&gt; &amp;#x1f601;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;1. Der Plan im Kalender
&lt;div id="1-der-plan-im-kalender" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#1-der-plan-im-kalender" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Das Herzstück ist ein &lt;strong&gt;Local Calendar&lt;/strong&gt; namens &lt;code&gt;calendar.auto_vacuum&lt;/code&gt;. Anders als bei klassischen Reinigungsplänen ist mein Kalender allerdings nicht &lt;strong&gt;lesbar für Menschen&lt;/strong&gt;, sondern &lt;strong&gt;lesbar für Home Assistant&lt;/strong&gt;. Drei Event-Typen sind hinterlegt, alle mit eigenen Wiederholungs-Regeln (&lt;code&gt;RRULE&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bereich-Events&lt;/strong&gt; geben an, an welchen Tagen welcher Raum dran ist. Der &lt;code&gt;summary&lt;/code&gt; folgt strikt dem Schema &lt;code&gt;area:&amp;lt;area_id&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;summary: area:wohnzimmer
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rrule: FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;summary: area:schlafzimmer
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rrule: FREQ=WEEKLY;BYDAY=TU,SA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Wiederholungs-Events&lt;/strong&gt; geben an, wie oft an einem Tag &lt;strong&gt;zusätzlich&lt;/strong&gt; gesaugt werden soll. Ohne Event bleibt es bei einem Durchgang, mit &lt;code&gt;repeat:once&lt;/code&gt; gibt es einen Extra-Durchgang (also zwei), mit &lt;code&gt;repeat:twice&lt;/code&gt; gibt es zwei Extras (also drei):&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;summary: repeat:once
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rrule: FREQ=WEEKLY;BYDAY=MO,FR&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Es lohnt sich, hier mit Bedacht zu entscheiden. Drei Durchgänge bedeuten &lt;strong&gt;dreifache Laufzeit&lt;/strong&gt; und &lt;strong&gt;dreifacher Lärm&lt;/strong&gt;. Mein Roborock zieht im &lt;em&gt;max&lt;/em&gt;-Modus außerdem ordentlich an der Batterie. &lt;code&gt;repeat:once&lt;/code&gt; oder &lt;code&gt;repeat:twice&lt;/code&gt; nutze ich nur an Tagen, an denen wir verlässlich nicht da sind.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Clean-Events&lt;/strong&gt; definieren Zeitfenster, in denen die Reinigung überhaupt anlaufen darf. Das sind die einzigen Events mit &lt;code&gt;dateTime&lt;/code&gt; statt &lt;code&gt;date&lt;/code&gt;, weil hier eine Uhrzeit zählt:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;summary: clean
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;start: 09:00, end: 13:00
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rrule: FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Auf diese Weise habe ich vormittags und nachmittags je ein Fenster definiert. Innerhalb dieser Fenster sieht der Plan zu, dass die Sache passiert. Außerhalb wird gar nicht erst angefangen.&lt;/p&gt;
&lt;h3 class="relative group"&gt;1a. Erläuterungen
&lt;div id="1a-erläuterungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#1a-erl%c3%a4uterungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Warum drei Event-Typen statt einem? Weil sie &lt;strong&gt;unabhängig voneinander&lt;/strong&gt; geändert werden können. Wenn ich morgen entscheide, dass das Schlafzimmer nur noch einmal pro Woche dran ist, ändere ich genau ein &lt;code&gt;area:&lt;/code&gt;-Event, nichts sonst. Wenn ich eine neue Putzphase mit drei Durchgängen ausprobieren möchte, lege ich ein &lt;code&gt;repeat:twice&lt;/code&gt;-Event an. Und wenn der Bauarbeiter-Lärm in der Nachbarschaft mich zwingt, ein Zeitfenster zu verschieben, fasse ich nur das &lt;code&gt;clean&lt;/code&gt;-Event an. &lt;strong&gt;Trennung der Zuständigkeiten&lt;/strong&gt;, ganz wie beim Coden &amp;#x1f604;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;2. Der Template Sensor: &amp;ldquo;Was steht heute an?&amp;rdquo;
&lt;div id="2-der-template-sensor-was-steht-heute-an" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#2-der-template-sensor-was-steht-heute-an" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Aus den Kalender-Events allein wird noch kein Reinigungsplan. Es braucht eine Stelle, die jeden Moment beantworten kann: &lt;em&gt;&amp;ldquo;Welche Räume stehen heute an, wie oft, und wann das nächste Mal?&amp;rdquo;&lt;/em&gt;. Genau das tut mein &lt;strong&gt;Trigger-basierter Template Sensor&lt;/strong&gt; &lt;code&gt;binary_sensor.auto_vacuum_schedule&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Bevor wir in den YAML-Schlund steigen, zur Orientierung das &lt;strong&gt;Output-Schema&lt;/strong&gt;, das der Sensor liefert. Sein State ist &lt;code&gt;on&lt;/code&gt;, sobald ein &lt;code&gt;clean&lt;/code&gt;-Fenster aktiv ist, sonst &lt;code&gt;off&lt;/code&gt;. Die Attribute sind die interessante Stelle:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;off&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# oder &amp;#34;on&amp;#34;, während eines clean-Fensters&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;attributes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;today&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;areas&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;flur&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repeat&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;next&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;areas&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;schlafzimmer&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;2026-05-23&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;flur&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;2026-05-22&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;wohnzimmer&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;2026-05-22&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repeat&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;once&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;2026-05-22&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Und so sieht der Sensor in voller Schönheit aus:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;triggers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;trigger&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;homeassistant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;trigger&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;time_pattern&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;hours&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;/1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;actions&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;calendar.get_events&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;start_date_time&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ now().date() }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;duration&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;days&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;calendar.auto_vacuum&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;response_variable&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;variables&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;clean_events&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ result[&amp;#34;calendar.auto_vacuum&amp;#34;].events
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | selectattr(&amp;#34;summary&amp;#34;, &amp;#34;eq&amp;#34;, &amp;#34;clean&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | sort(attribute=&amp;#34;start&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | list }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;next_areas&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set areas = result[&amp;#34;calendar.auto_vacuum&amp;#34;].events
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | selectattr(&amp;#34;summary&amp;#34;, &amp;#34;search&amp;#34;, &amp;#34;area:&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | groupby(attribute=&amp;#34;summary&amp;#34;) %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set data = namespace(areas=[]) %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% for area, items in areas %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set data.areas = data.areas + [(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; area | replace(&amp;#34;area:&amp;#34;, &amp;#34;&amp;#34;),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; items
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | sort(attribute=&amp;#34;start&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | map(attribute=&amp;#34;start&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | first
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; )] %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% endfor %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ dict(data.areas) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;next_repeat&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set repeat = result[&amp;#34;calendar.auto_vacuum&amp;#34;].events
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | selectattr(&amp;#34;summary&amp;#34;, &amp;#34;search&amp;#34;, &amp;#34;repeat:&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | groupby(attribute=&amp;#34;summary&amp;#34;) %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set data = namespace(repeat=[]) %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% for rep, items in repeat %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set data.repeat = data.repeat + [(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rep | replace(&amp;#34;repeat:&amp;#34;, &amp;#34;&amp;#34;),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; items
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | sort(attribute=&amp;#34;start&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | map(attribute=&amp;#34;start&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | first
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; )] %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% endfor %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ dict(data.repeat) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;binary_sensor&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;auto_vacuum_schedule&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;unique_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;auto_vacuum_schedule&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set clean_ev_start = clean_events
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | map(attribute=&amp;#34;start&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | map(&amp;#34;as_datetime&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | list %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set clean_ev_end = clean_events
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | map(attribute=&amp;#34;end&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | map(&amp;#34;as_datetime&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | list %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set clean_ev_map = zip(clean_ev_start, clean_ev_end) | list %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ clean_ev_map
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | rejectattr(&amp;#34;0&amp;#34;, &amp;#34;ge&amp;#34;, now())
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | rejectattr(&amp;#34;1&amp;#34;, &amp;#34;lt&amp;#34;, now())
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | list
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | count &amp;gt; 0 }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;attributes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;next&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;areas&amp;#34;: next_areas,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;repeat&amp;#34;: next_repeat
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; } }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;today&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set data = namespace(areas=[], repeat=[]) %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% for area in next_areas.keys() %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% if (next_areas[area] | as_datetime).date() == now().date() %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set data.areas = data.areas + [area] %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% endif %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% endfor %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% for rep in next_repeat.keys() %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% if (next_repeat[rep] | as_datetime).date() == now().date() %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set data.repeat = data.repeat + [rep] %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% endif %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% endfor %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;areas&amp;#34;: data.areas,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;repeat&amp;#34;:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 3 if &amp;#34;twice&amp;#34; in data.repeat
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; else 2 if &amp;#34;once&amp;#34; in data.repeat
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; else 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; } }}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;2a. Erläuterungen
&lt;div id="2a-erläuterungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#2a-erl%c3%a4uterungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Sieht nach viel aus, ist im Grunde aber überschaubar. Lass uns das einmal von oben nach unten durchgehen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Triggers.&lt;/strong&gt; Der Sensor wird beim &lt;em&gt;Home Assistant&lt;/em&gt; Start und einmal pro Stunde neu berechnet. Häufiger ist nicht nötig, weil sich der Kalender ohnehin nicht im Minutentakt ändert.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;calendar.get_events&lt;/code&gt;.&lt;/strong&gt; Holt alle Events der nächsten sechs Tage und legt sie als &lt;code&gt;result&lt;/code&gt; ab. Das ist die einzige externe Datenquelle, alles andere ist Rechenarbeit auf dem Ergebnis.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variable &lt;code&gt;clean_events&lt;/code&gt;.&lt;/strong&gt; Filtert auf die &lt;code&gt;summary: clean&lt;/code&gt;-Einträge. Aus dieser Liste wird gleich der State berechnet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variable &lt;code&gt;next_areas&lt;/code&gt;.&lt;/strong&gt; Gruppiert alle &lt;code&gt;area:*&lt;/code&gt;-Events nach Bereich und schnappt sich pro Bereich den &lt;strong&gt;frühesten&lt;/strong&gt; kommenden Termin. Ergibt das Dict im &lt;code&gt;next.areas&lt;/code&gt;-Attribut.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variable &lt;code&gt;next_repeat&lt;/code&gt;.&lt;/strong&gt; Macht dasselbe für &lt;code&gt;repeat:*&lt;/code&gt;-Events und liefert pro Wiederholungs-Typ (&lt;code&gt;once&lt;/code&gt;, &lt;code&gt;twice&lt;/code&gt;) den nächsten Termin.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;State.&lt;/strong&gt; Vergleicht &lt;code&gt;now()&lt;/code&gt; gegen die Start- und End-Zeiten der &lt;code&gt;clean&lt;/code&gt;-Events. Sobald &lt;strong&gt;genau ein&lt;/strong&gt; Fenster aktuell läuft, ist der Sensor &lt;code&gt;on&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attribut &lt;code&gt;next&lt;/code&gt;.&lt;/strong&gt; Einfach die beiden Dicts gebündelt - das ist die &lt;strong&gt;Status-Ebene&lt;/strong&gt; für die Todo-Liste.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attribut &lt;code&gt;today&lt;/code&gt;.&lt;/strong&gt; Filtert beide Dicts auf das heutige Datum. Aus den Wiederholungs-Treffern entsteht der numerische &lt;code&gt;repeat&lt;/code&gt;-Wert: drei bei &lt;code&gt;twice&lt;/code&gt;, zwei bei &lt;code&gt;once&lt;/code&gt;, sonst eins. Das ist die &lt;strong&gt;Aktions-Ebene&lt;/strong&gt; für die Automation.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Beachte die Reihenfolge in der &lt;code&gt;repeat&lt;/code&gt;-Logik: &lt;code&gt;twice&lt;/code&gt; wird &lt;strong&gt;vor&lt;/strong&gt; &lt;code&gt;once&lt;/code&gt; geprüft. Wäre es umgekehrt, würde ein Tag, an dem beide Events liegen, fälschlich nur zwei Durchgänge bekommen. So gewinnt immer der höhere Wert.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Das schöne Detail an diesem Sensor ist, dass er &lt;strong&gt;komplett ohne Helfer&lt;/strong&gt; auskommt. Keine &lt;code&gt;input_*&lt;/code&gt;-Entities, keine externen Trigger-Quellen, kein Zustand außer dem Kalender. Wenn morgen mein Setup zerschießt, reichen Kalender plus Template-Sensor, um das System wieder ans Laufen zu bringen.&lt;/p&gt;
&lt;h2 class="relative group"&gt;3. Das Script: Areas zu Roborock-Segmenten übersetzen
&lt;div id="3-das-script-areas-zu-roborock-segmenten-übersetzen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#3-das-script-areas-zu-roborock-segmenten-%c3%bcbersetzen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Home Assistant&lt;/em&gt; kennt Räume als &lt;code&gt;area_id&lt;/code&gt;. Mein Roborock kennt Räume als &lt;strong&gt;numerische Segment-IDs&lt;/strong&gt;, die er sich beim Mapping selbst vergibt. Das passt nicht zusammen. Also baue ich die Brücke in einem Skript namens &lt;code&gt;script.turn_on_vacuum_segment_cleaning&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;alias&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Segmentreinigung starten&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;icon&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;mdi:robot-vacuum&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;fields&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;area&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Raum&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;description&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Name des Raums&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;required&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;area&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;multiple&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repeat&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Wiederholungen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;description&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Wie oft die Segmente gesaugt werden sollen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;required&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;default&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;number&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;min&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;max&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;step&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;sequence&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;roborock.get_maps&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;: {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;vacuum.roborock_s7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;response_variable&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;variables&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;segments&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set rooms = result[&amp;#34;vacuum.roborock_s7&amp;#34;].maps
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | selectattr(&amp;#34;name&amp;#34;, &amp;#34;eq&amp;#34;, &amp;#34;Obergeschoss&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | map(attribute=&amp;#34;rooms&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | first %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set room_map = zip(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rooms.values() | map(&amp;#34;area_id&amp;#34;),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; rooms.keys()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; ) | list %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ room_map | selectattr(&amp;#34;0&amp;#34;, &amp;#34;in&amp;#34;, area) | map(attribute=&amp;#34;1&amp;#34;) | list }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;vacuum.send_command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;command&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;app_segment_clean&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;params&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;segments&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ segments }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repeat&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ repeat }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;vacuum.roborock_s7&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;3a. Erläuterungen
&lt;div id="3a-erläuterungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#3a-erl%c3%a4uterungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Drei Schritte, drei Ideen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Das Script fragt die &lt;a href="https://www.home-assistant.io/integrations/roborock/" target="_blank" rel="noopener noreferrer"&gt;Roborock Integration &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; per &lt;code&gt;roborock.get_maps&lt;/code&gt; nach den &lt;strong&gt;bekannten Karten&lt;/strong&gt; und legt die Antwort in &lt;code&gt;result&lt;/code&gt; ab. Bei einer Karte pro Etage filtere ich gezielt die Karte namens &lt;em&gt;Obergeschoss&lt;/em&gt; heraus.&lt;/li&gt;
&lt;li&gt;Aus den Räumen der Karte baue ich eine &lt;strong&gt;Mapping-Liste&lt;/strong&gt; der Form &lt;code&gt;(area_id, segment_id)&lt;/code&gt;. Das ist das eigentliche Bindeglied zwischen Home-Assistant-Welt und Roborock-Welt.&lt;/li&gt;
&lt;li&gt;Anschließend filtere ich auf jene &lt;code&gt;area_id&lt;/code&gt;s, die als Argument übergeben wurden, und feuere das &lt;strong&gt;proprietäre &lt;code&gt;app_segment_clean&lt;/code&gt;-Kommando&lt;/strong&gt; an den Sauger ab. Inklusive der gewünschten Wiederholungs-Anzahl.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="warning"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Warning
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Damit dieses Mapping funktioniert, müssen die &lt;strong&gt;Raumnamen im Roborock&lt;/strong&gt; mit den &lt;strong&gt;Area-IDs in Home Assistant&lt;/strong&gt; korrespondieren. Bei mir heißt der Roborock-Raum &lt;em&gt;Wohnzimmer&lt;/em&gt;, die Area in HA &lt;code&gt;wohnzimmer&lt;/code&gt;. Roborock leitet daraus dieselbe &lt;code&gt;area_id&lt;/code&gt; ab. Wenn deine Namen abweichen, musst du die Map einmal manuell pflegen oder via Lookup-Tabelle ergänzen.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;4. Die Trigger-Automation: &amp;ldquo;Saug, wenn&amp;rsquo;s niemanden stört&amp;rdquo;
&lt;div id="4-die-trigger-automation-saug-wenns-niemanden-stört" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#4-die-trigger-automation-saug-wenns-niemanden-st%c3%b6rt" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Jetzt kommt der Klebstoff. Diese Automation entscheidet, &lt;strong&gt;wann&lt;/strong&gt; der Sauger tatsächlich loslaufen darf:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;alias&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Staubsauger: starten&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;mode&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;single&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;trigger&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;input_select.presence_mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;from&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;zuhause&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;to&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;abwesend&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;for&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;00:15:00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;person.partner&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;to&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;not_home&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;for&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;00:30:00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;time_pattern&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;minutes&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;/15&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;seconds&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;40&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;calendar&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;calendar.auto_vacuum&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;condition&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;binary_sensor.auto_vacuum_schedule&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;on&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;input_boolean.auto_vacuumed_today&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;input_boolean.vacation_mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;off&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;input_select.sleep_mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;aus&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;or&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;conditions&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;input_select.presence_mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;abwesend&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;for&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;00:15:00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;not&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;conditions&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;person.partner&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;home&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;media_player.wohnzimmer_tv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;off&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;for&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;00:10:00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;action&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;script.turn_on_vacuum_segment_cleaning&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;area&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ state_attr(&amp;#39;binary_sensor.auto_vacuum_schedule&amp;#39;, &amp;#39;today&amp;#39;).areas or [] }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repeat&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ state_attr(&amp;#39;binary_sensor.auto_vacuum_schedule&amp;#39;, &amp;#39;today&amp;#39;).repeat or 1 }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;wait_for_trigger&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;binary_sensor.roborock_s7_reinigen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;from&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;off&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;to&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;on&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;continue_on_timeout&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;timeout&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;00:05:00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;if&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;template&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;value_template&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ not wait.trigger }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;then&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;notify.mobile_app&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;message&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Staubsauger sollte gestartet werden, reinigt aber nicht.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;stop&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Der Staubsauger ist nicht losgefahren.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;error&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;input_boolean.turn_on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;input_boolean.auto_vacuumed_today&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;vacuum.set_fan_speed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;vacuum.roborock_s7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;fan_speed&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;max&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;select.select_option&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;select.roborock_s7_wisch_intensitat&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;option&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;off&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;4a. Erläuterungen
&lt;div id="4a-erläuterungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#4a-erl%c3%a4uterungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Vier Trigger, eine Wahrheit:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Presence-Mode wechselt auf abwesend&lt;/strong&gt; für mindestens 15 Minuten. Wenn die ganze Familie das Haus verlässt, beginnt das Fenster.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Partner geht außer Haus`&lt;/strong&gt; für 30 Minuten. Mein Büro ist auf einem anderen Stockwerk, also kann gesaugt werden, wenn meine Frau nicht da ist.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alle 15 Minuten ein Tick&lt;/strong&gt;, weil sich Zustände auch zwischendurch ändern können, ohne dass ein State-Trigger feuert.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kalender-Start eines &lt;code&gt;clean&lt;/code&gt;-Events&lt;/strong&gt;. Wenn das Zeitfenster aufgeht und gerade niemand da ist, soll der Sauger loslegen.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Die Conditions sind das eigentliche Hirn. Sie stellen sicher, dass der Sauger &lt;strong&gt;wirklich&lt;/strong&gt; loslaufen darf:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;binary_sensor.auto_vacuum_schedule&lt;/code&gt; muss &lt;code&gt;on&lt;/code&gt; sein, sprich: heute steht etwas an und das Zeitfenster läuft.&lt;/li&gt;
&lt;li&gt;Weder &lt;em&gt;Urlaubsmodus&lt;/em&gt; noch &lt;em&gt;heute schon gesaugt&lt;/em&gt; dürfen aktiv sein.&lt;/li&gt;
&lt;li&gt;Kein &lt;strong&gt;Schlaf-Modus&lt;/strong&gt;, kein laufender &lt;strong&gt;Fernseher&lt;/strong&gt; seit mindestens 10 Minuten.&lt;/li&gt;
&lt;li&gt;Die Anwesenheits-Bedingung wird im &lt;code&gt;or&lt;/code&gt;-Block doppelt geprüft, damit das System bei einer einzelnen Person im Haus auch reagiert, sobald sie unterwegs ist.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Im &lt;code&gt;action&lt;/code&gt;-Block wird das Script gerufen, dann &lt;strong&gt;fünf Minuten lang&lt;/strong&gt; auf das Live-Signal &lt;em&gt;&amp;ldquo;Sauger reinigt&amp;rdquo;&lt;/em&gt; gewartet. Springt er nicht an, gibt es eine Push-Notification - das hat mich am Anfang vor mehr als einem stillen Fehlversuch bewahrt &amp;#x1f604;. Erfolg setzt das &lt;em&gt;gesaugt-heute&lt;/em&gt;-Flag, schaltet den Lüfter auf maximale Saugstufe und deaktiviert die Wischfunktion, weil bei mir nur gesaugt wird.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Wer wischen will, lässt die &lt;code&gt;select.select_option&lt;/code&gt;-Aktion einfach weg oder stellt sie auf den jeweilig sinnvollen Wert.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;5. Die Todo-Liste: Status fürs Dashboard
&lt;div id="5-die-todo-liste-status-fürs-dashboard" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#5-die-todo-liste-status-f%c3%bcrs-dashboard" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Das Schöne an einem &lt;code&gt;todo&lt;/code&gt;-Entity in &lt;em&gt;Home Assistant&lt;/em&gt; ist, dass es als &lt;strong&gt;interaktive Liste&lt;/strong&gt; auf dem Dashboard erscheint - inklusive Fälligkeitsdatum und Abhaken per Klick. Genau das wollte ich für meine Frau und mich: eine Anzeige, die zeigt, &lt;strong&gt;was heute ansteht&lt;/strong&gt; und &lt;strong&gt;was schon erledigt ist&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Klare Ansage vorweg, damit kein Missverständnis entsteht: die Todo-Liste ist in meinem Setup eine &lt;strong&gt;reine Statusanzeige&lt;/strong&gt;, kein Steuer-Eingang. Die Trigger-Automation aus dem vorigen Kapitel liest sie &lt;strong&gt;nicht&lt;/strong&gt;. Sie entscheidet allein anhand des Template-Sensors, welche Räume heute fällig sind. Die Todo-Liste wird also vom System &lt;strong&gt;geschrieben&lt;/strong&gt;, aber nicht vom System &lt;strong&gt;gelesen&lt;/strong&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Damit das Schreiben sauber funktioniert, kümmern sich zwei Automationen um die Liste: eine &lt;strong&gt;nächtliche Aufbau-Automation&lt;/strong&gt; und eine &lt;strong&gt;Abhak-Automation&lt;/strong&gt; nach erfolgreicher Reinigung.&lt;/p&gt;
&lt;h3 class="relative group"&gt;5a. Nachts aufbauen
&lt;div id="5a-nachts-aufbauen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#5a-nachts-aufbauen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;alias&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Staubsauger: Todos bauen&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;mode&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;single&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;trigger&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;at&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;00:05:00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;action&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;input_boolean.turn_off&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;input_boolean.auto_vacuumed_today&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;todo.get_items&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;status&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;completed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;response_variable&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;todo.auto_vacuum&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;repeat&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;for_each&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ result[&amp;#39;todo.auto_vacuum&amp;#39;][&amp;#39;items&amp;#39;] }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;sequence&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;variables&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;new_due&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set nxt = state_attr(&amp;#34;binary_sensor.auto_vacuum_schedule&amp;#34;, &amp;#34;next&amp;#34;).areas %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ nxt.get(repeat.item.summary | area_id) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;if&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;template&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;value_template&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ new_due is not none }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;then&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;todo.update_item&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;item&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ repeat.item.summary }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;status&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;needs_action&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;due_date&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ new_due | as_timestamp | timestamp_custom(&amp;#39;%Y-%m-%d&amp;#39;) }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;todo.auto_vacuum&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 class="relative group"&gt;5a. Erläuterungen
&lt;div id="5a-erläuterungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#5a-erl%c3%a4uterungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Diese Automation läuft um &lt;strong&gt;fünf nach Mitternacht&lt;/strong&gt; und tut drei Dinge:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sie setzt das &lt;code&gt;input_boolean.auto_vacuumed_today&lt;/code&gt; auf &lt;code&gt;off&lt;/code&gt;, damit der neue Tag offen ist.&lt;/li&gt;
&lt;li&gt;Sie liest alle &lt;strong&gt;abgeschlossenen Items&lt;/strong&gt; aus der Todo-Liste.&lt;/li&gt;
&lt;li&gt;Für jedes dieser Items prüft sie im &lt;code&gt;next.areas&lt;/code&gt;-Attribut des Template-Sensors, &lt;strong&gt;wann der zugehörige Raum als Nächstes fällig&lt;/strong&gt; ist. Stimmt das Datum, wird das Item wieder auf &lt;code&gt;needs_action&lt;/code&gt; gesetzt und das Fälligkeitsdatum aktualisiert.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Die Filter-Zauberei mit &lt;code&gt;repeat.item.summary | area_id&lt;/code&gt; ist die Stelle, an der die Magie greift: weil der Todo-Item-Titel exakt dem Raumnamen entspricht (zum Beispiel &lt;em&gt;Wohnzimmer&lt;/em&gt;), kann &lt;em&gt;Home Assistant&lt;/em&gt; daraus automatisch die &lt;code&gt;area_id&lt;/code&gt; ableiten. &lt;strong&gt;Trennung der Zuständigkeiten&lt;/strong&gt;, schon wieder.&lt;/p&gt;
&lt;h3 class="relative group"&gt;5b. Nach Reinigung abhaken
&lt;div id="5b-nach-reinigung-abhaken" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#5b-nach-reinigung-abhaken" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;alias&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Staubsauger: Todos abhaken&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;mode&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;single&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;trigger&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;input_boolean.auto_vacuumed_today&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;from&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;off&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;to&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;on&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;action&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;todo.get_items&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;status&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;needs_action&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;response_variable&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;todo.auto_vacuum&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;repeat&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;for_each&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ result[&amp;#39;todo.auto_vacuum&amp;#39;][&amp;#39;items&amp;#39;] | selectattr(&amp;#39;due&amp;#39;, &amp;#39;defined&amp;#39;) | list }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;sequence&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;if&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;template&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;value_template&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ repeat.item.due | as_timestamp &amp;lt;= now().date() | as_timestamp }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;then&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;action&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;todo.update_item&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;item&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ repeat.item.summary }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;status&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;completed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;todo.auto_vacuum&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 class="relative group"&gt;5b. Erläuterungen
&lt;div id="5b-erläuterungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#5b-erl%c3%a4uterungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Diese Automation triggert exakt dann, wenn &lt;code&gt;input_boolean.auto_vacuumed_today&lt;/code&gt; von &lt;code&gt;off&lt;/code&gt; auf &lt;code&gt;on&lt;/code&gt; springt - also genau nach einer erfolgreichen automatischen Reinigung. Sie holt sich alle &lt;strong&gt;offenen&lt;/strong&gt; Items und hakt jene ab, deren &lt;code&gt;due&lt;/code&gt;-Datum &lt;strong&gt;heute oder früher&lt;/strong&gt; liegt. Das deckt sich exakt mit den Räumen, die der Sauger gerade abgefahren hat.&lt;/p&gt;
&lt;p&gt;Der &lt;code&gt;input_boolean.auto_vacuumed_today&lt;/code&gt; ist hier das &lt;strong&gt;zentrale Signal&lt;/strong&gt;, das die drei Automationen miteinander koppelt: er wird von der Trigger-Automation gesetzt, von der Abhak-Automation gelesen und von der Aufbau-Automation nachts zurückgesetzt. &lt;strong&gt;Ein Helfer, drei Rollen&lt;/strong&gt; - so soll das sein &amp;#x1f604;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Was die Todo-Liste konkret leistet
&lt;div id="was-die-todo-liste-konkret-leistet" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-die-todo-liste-konkret-leistet" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Ergebnis: jeden Morgen schaut meine Frau aufs Dashboard und sieht &lt;em&gt;&amp;ldquo;Wohnzimmer (heute), Flur (heute), Schlafzimmer (übermorgen)&amp;rdquo;&lt;/em&gt;. Sobald der Roboter fertig ist, fliegen die heutigen Räume in den erledigt-Stapel. Nachts wird die Liste neu sortiert und mit aktuellen Fälligkeitsdaten versehen.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="note"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Note
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Manuelles Abhaken eines Items hat in diesem Setup &lt;strong&gt;keinen Einfluss&lt;/strong&gt; auf die Reinigung. Wer also &amp;ldquo;Wohnzimmer&amp;rdquo; morgens abhakt, weil er mit dem Akkusauger durch war, sieht zwar die Liste hübscher aussehen, der Roboter fährt das Wohnzimmer aber trotzdem an. Das ist eine bewusste Designentscheidung: die Logik &lt;em&gt;was wird gereinigt&lt;/em&gt; lebt im Kalender, nicht in der Todo-Liste. Wenn ich das ändern möchte, ändere ich den Kalender, nicht ein Häkchen.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Stolpersteine
&lt;div id="stolpersteine" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#stolpersteine" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Hier noch ein paar Beobachtungen aus dem Echtbetrieb:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Helfer-Inflation.&lt;/strong&gt; Du brauchst mindestens drei Input-Booleans (&lt;code&gt;auto_vacuumed_today&lt;/code&gt;, &lt;code&gt;vacation_mode&lt;/code&gt;, plus eventuell weitere) und ein paar Input-Selects (&lt;code&gt;presence_mode&lt;/code&gt;, &lt;code&gt;sleep_mode&lt;/code&gt;). Das ist eine Menge Klick-Arbeit in der UI - lohnt sich aber, weil die Helfer in anderen Automationen wiederverwendet werden.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Karten-Namen sind fragil.&lt;/strong&gt; Sobald du deine Roborock-Karte einmal umbenennst oder neu erstellst, ändern sich die Segment-IDs. Das Mapping im Script bleibt funktional, weil es über Namen läuft - aber genau hier liegt der Teufel im Detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Roborock cloud vs. local.&lt;/strong&gt; Die offizielle &lt;a href="https://www.home-assistant.io/integrations/roborock/" target="_blank" rel="noopener noreferrer"&gt;Roborock Integration &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; nutzt die Roborock-Cloud. Wer das nicht mag - ich kann das gut nachvollziehen, Stichwort &lt;strong&gt;Cloudzwang&lt;/strong&gt; - findet auf GitHub Alternativen mit lokalem Zugriff. Das Setup hier funktioniert mit beiden, weil es nur die Standard-Services aufruft.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wartezeit auf den Start.&lt;/strong&gt; Manche Roborock-Modelle brauchen nach dem &lt;code&gt;app_segment_clean&lt;/code&gt;-Kommando einige Sekunden, bis sie überhaupt aus der Dock fahren. Mein Timeout von fünf Minuten ist großzügig gewählt - es reichen wahrscheinlich zwei. Probier es aus.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Was als zweijähriger Cliffhanger angefangen hat, ist heute eines der Setups, das mir im Alltag am wenigsten Aufmerksamkeit kostet und am meisten zurückgibt. Der Sauger läuft, &lt;strong&gt;wenn er soll&lt;/strong&gt;. Er läuft &lt;strong&gt;nicht&lt;/strong&gt;, wenn er nicht soll. Die Familie sieht den Status, ohne dass ich erklären müsste, was gerade automatisch passiert. &lt;strong&gt;Stichwort:&lt;/strong&gt; &lt;em&gt;Women Acceptance Factor&lt;/em&gt;, einmal mehr im grünen Bereich &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;Der eigentliche Aha-Moment war für mich, dass der Reinigungsplan jetzt &lt;strong&gt;textuell&lt;/strong&gt; in einem Kalender lebt. Wenn ich morgen entscheide, dass das Schlafzimmer dreimal die Woche dran sein soll, ändere ich genau eine &lt;code&gt;RRULE&lt;/code&gt; und der Rest der Pipeline zieht von selbst nach. Keine Skript-Anpassung, keine YAML-Migration, kein Helfer-Karussell.&lt;/p&gt;
&lt;p&gt;Vielleicht magst du das Setup für dein Zuhause adaptieren. Vielleicht hast du eine bessere Idee, wie man das alles noch eleganter löst - dann schreib mir gern. Bis dahin: &lt;strong&gt;Viel Spaß&lt;/strong&gt; beim Reinigen lassen &amp;#x1f60e;!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@houston100?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;YoonJae Baik &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/weisser-kurzbeschichteter-kleiner-hund-auf-braunem-holzboden-p7MsAMLSbbU?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Wie ich mein Smart Home mit KI auditiere</title><link href="https://tbsch.de/post/2026-05-21-wie-ich-mein-smart-home-mit-ki-auditiere/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2026-05-21-wie-ich-mein-smart-home-mit-ki-auditiere/</id><published>2026-05-21T00:00:00Z</published><updated>2026-05-21T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="smart-home"/><category term="home-assistant"/><category term="mcp"/><category term="ki"/><category term="workflow"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2026-05-21-wie-ich-mein-smart-home-mit-ki-auditiere/featured.webp"/><summary type="html">Mein Home Assistant ist über die Jahre gewachsen. Ein bisschen zu sehr. Was passiert, wenn ich Claude per MCP an die Maschine lasse?</summary><content type="html">&lt;div class="lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl"&gt;
Wenn dein Smart Home eine eigene Stadtverwaltung bräuchte, wird es Zeit für einen Spaziergang durch den Maschinenraum.
&lt;/div&gt;
&lt;p&gt;Kennst du diesen Moment, in dem dir auffällt, dass dein Smart Home dir &lt;strong&gt;ein bisschen entglitten ist&lt;/strong&gt;? Bei mir war es ein ganz normaler Sonntag. Ich saß mit einem Kaffee vor &lt;em&gt;Home Assistant&lt;/em&gt;, wollte „nur kurz&amp;quot; einen Sensor neu anlernen - und stolperte stattdessen über &lt;strong&gt;eine Automatisierung, die ich nicht mehr erklären konnte&lt;/strong&gt;. Wofür war die da? Wann habe ich die gebaut? Ich hatte keine Ahnung mehr &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;Wenig später wollte ich mich überzeugen, dass ich alles im Griff habe. Das war ein Fehler: Im Reiter &lt;em&gt;Geräte und Dienste&lt;/em&gt; leuchteten gefühlt überall kleine Warnsymbole, und in der Sensor-Liste sah ich Einträge, deren Namen mir nicht einmal mehr etwas sagten. &lt;strong&gt;Ein gewachsenes Setup hat das so an sich&lt;/strong&gt;: es ist wie ein Garten, in dem zwischen den Stauden plötzlich Bäume stehen, die du augenscheinlich nie gepflanzt hast.&lt;/p&gt;
&lt;p&gt;Ein paar Zahlen, damit du weißt, wovon ich spreche: meine Instanz zählt aktuell &lt;strong&gt;1.293 Entitäten&lt;/strong&gt;, &lt;strong&gt;80 Automationen&lt;/strong&gt; und &lt;strong&gt;95 Sensoren, die mir &lt;code&gt;unavailable&lt;/code&gt; zurufen&lt;/strong&gt;. Verteilt über 13 Bereiche, gewachsen über Jahre. Ich glaube, jeder, der sein Smart Home länger als zwei Jahre pflegt, kennt das. Und so richtig &lt;strong&gt;Lust auf einen Aufräum-Samstag&lt;/strong&gt; hat man halt auch nie.&lt;/p&gt;
&lt;p&gt;Seit ein paar Tagen probiere ich etwas Neues aus, und ich muss gestehen: es &lt;strong&gt;verändert tatsächlich&lt;/strong&gt;, wie ich mein Setup pflege. Die Idee ist eigentlich ganz einfach: Ich lasse &lt;strong&gt;&lt;a href="https://claude.com" target="_blank" rel="noopener noreferrer"&gt;Claude &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; über das &lt;strong&gt;&lt;a href="https://modelcontextprotocol.io" target="_blank" rel="noopener noreferrer"&gt;Model Context Protocol (MCP) &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; direkt mit meinem &lt;strong&gt;&lt;a href="https://www.home-assistant.io" target="_blank" rel="noopener noreferrer"&gt;Home Assistant &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; sprechen.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Was ist MCP überhaupt?
&lt;div id="was-ist-mcp-überhaupt" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-ist-mcp-%c3%bcberhaupt" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;&lt;strong&gt;MCP&lt;/strong&gt; (Model Context Protocol) ist ein offener Standard, mit dem Sprachmodelle wie &lt;em&gt;Claude&lt;/em&gt; &lt;strong&gt;strukturiert&lt;/strong&gt; mit externen Systemen reden können. Statt der KI eine Wand aus Text vorzuwerfen und auf das Beste zu hoffen, bekommt sie einen klaren Werkzeugkasten an die Hand: &lt;em&gt;zeig mir alle Entitäten in diesem Bereich, lies die Historie dieses Sensors, suche in den Automationen nach allem, was diese Lampe anfasst&lt;/em&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Für &lt;em&gt;Home Assistant&lt;/em&gt; gibt es dafür mittlerweile einen MCP-Server, den du im &lt;strong&gt;&lt;a href="https://hacs.xyz" target="_blank" rel="noopener noreferrer"&gt;HACS &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; unter dem Namen &lt;em&gt;&lt;a href="https://github.com/homeassistant-ai/ha-mcp" target="_blank" rel="noopener noreferrer"&gt;ha-mcp &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/em&gt; findest. Die Einrichtung selbst ist erstaunlich unspektakulär: Repository hinzufügen, einen Service-Account in HA anlegen, ein &lt;strong&gt;Long-Lived Access Token&lt;/strong&gt;&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; erzeugen, in &lt;em&gt;&lt;a href="https://claude.com/download" target="_blank" rel="noopener noreferrer"&gt;Claude Desktop &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/em&gt; den Server eintragen. &lt;strong&gt;Nach 15 Minuten&lt;/strong&gt; kannst du loslegen. So einfach ist das.&lt;/p&gt;
&lt;p&gt;Wichtig ist mir an der Stelle eines: die Verbindung läuft bei mir &lt;strong&gt;ausschließlich lokal&lt;/strong&gt;. &lt;em&gt;Claude Desktop&lt;/em&gt; spricht direkt mit meiner HA-Instanz im eigenen Netzwerk. Mein Heimnetz &lt;strong&gt;verlässt&lt;/strong&gt; dabei genau das, was zur &lt;strong&gt;Sprachverarbeitung&lt;/strong&gt; an die Anthropic-API geht - und das entscheide ich pro Frage. Wer regelmäßig hier mitliest, weiß: an dem Punkt bin ich &lt;strong&gt;pingelig&lt;/strong&gt; &amp;#x1f604;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Und wer ist eigentlich dieser &lt;em&gt;Claude&lt;/em&gt;?
&lt;div id="und-wer-ist-eigentlich-dieser-claude" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#und-wer-ist-eigentlich-dieser-claude" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Falls dir der Name nichts sagt: &lt;em&gt;Claude&lt;/em&gt; ist ein &lt;strong&gt;KI-Assistent&lt;/strong&gt; der Firma &lt;strong&gt;&lt;a href="https://www.anthropic.com" target="_blank" rel="noopener noreferrer"&gt;Anthropic &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt;, vergleichbar mit &lt;em&gt;ChatGPT&lt;/em&gt;, aber mit eigenem Charakter und einem deutlich stärkeren Fokus auf &lt;strong&gt;Sicherheit, Nachvollziehbarkeit und Datenhygiene&lt;/strong&gt;. Ich nutze ihn seit über einem Jahr im Alltag, am intensivsten am Schreibtisch über die &lt;em&gt;&lt;a href="https://claude.com/download" target="_blank" rel="noopener noreferrer"&gt;Claude Desktop &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/em&gt;-App. Mir liegt der Stil sehr, weil er sachlich bleibt, ehrlich auf Grenzen hinweist und nicht jeden Vorschlag mit drei Bullshit-Bingo-Wörtern garniert.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Ein wahrer Game-Changer, der dein Smart Home auf das nächste Level hebt.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Na, kommt dir bekannt vor &amp;#x1f601;?&lt;/p&gt;
&lt;p&gt;Was die Sache kostet: für gelegentliches Ausprobieren gibt es eine &lt;strong&gt;kostenlose Variante&lt;/strong&gt; mit Tageslimit, die zum Reinschnuppern völlig reicht. Wer Claude regelmäßig nutzt, landet beim Abo: &lt;strong&gt;&lt;a href="https://claude.com/pricing" target="_blank" rel="noopener noreferrer"&gt;Claude Pro &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; kostet aktuell &lt;strong&gt;rund 20 Euro im Monat&lt;/strong&gt;, hebt das Limit deutlich an, gibt Zugriff auf das aktuelle Spitzenmodell und schaltet Funktionen wie &lt;strong&gt;MCP-Integrationen&lt;/strong&gt; in der Desktop-App frei. Für Vielnutzer gibt es zusätzlich &lt;strong&gt;&lt;a href="https://claude.com/pricing" target="_blank" rel="noopener noreferrer"&gt;Claude Max &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; ab etwa &lt;strong&gt;100 Euro im Monat&lt;/strong&gt;, und für Entwickler oder Automatisierungen die &lt;strong&gt;&lt;a href="https://www.anthropic.com/api" target="_blank" rel="noopener noreferrer"&gt;API &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt;, bei der du pro verbrauchtem Token zahlst.&lt;/p&gt;
&lt;p&gt;Für das, was ich in diesem Beitrag beschreibe, reicht &lt;strong&gt;Claude Pro&lt;/strong&gt; völlig aus.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Fünf Sachen, für die ich es tatsächlich nutze
&lt;div id="fünf-sachen-für-die-ich-es-tatsächlich-nutze" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#f%c3%bcnf-sachen-f%c3%bcr-die-ich-es-tats%c3%a4chlich-nutze" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Nach ein paar Abenden Herumspielen haben sich bei mir ein paar Anwendungsfälle herauskristallisiert. Nicht alle sind gleich nützlich - ich sortiere sie nach &lt;em&gt;„wie oft hole ich es wirklich aus meiner Trickkiste&amp;quot;&lt;/em&gt;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Beispiel: Aufräumen, ohne dass es weh tut
&lt;div id="beispiel-aufräumen-ohne-dass-es-weh-tut" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#beispiel-aufr%c3%a4umen-ohne-dass-es-weh-tut" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Damit habe ich angefangen, weil es schlicht die Sache war, die am längsten überfällig war. Die Fragen, die ich Claude tatsächlich gestellt habe, klangen ungefähr so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;„Welche meiner Integrationen sind kaputt, und warum?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Liste mir die 95 unavailable Sensoren, gruppiert nach Integration.&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Welche Automationen wurden in den letzten 6 Monaten nie ausgelöst?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Welche Entitäten gehören zu keinem Bereich?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In der HA-UI ist das ein &lt;strong&gt;halber Samstagvormittag&lt;/strong&gt;, weil du dich durch Integrationen, Geräte und Logs klicken musst. Über MCP habe ich die Antwort in &lt;strong&gt;30 Sekunden&lt;/strong&gt; als sortierte Liste, oft direkt mit einem ersten Vorschlag, &lt;em&gt;was&lt;/em&gt; eigentlich zu tun wäre.&lt;/p&gt;
&lt;p&gt;Was dabei rauskam, hat mich übrigens nicht überrascht, aber es war trotzdem ernüchternd: etwa die Hälfte meiner unavailable Sensoren hängt schlicht an &lt;strong&gt;Integrationen, die ich nicht mehr nutze&lt;/strong&gt;. Die andere Hälfte sind &lt;strong&gt;Geräte, die ich längst entsorgt habe&lt;/strong&gt; - deren Entitäten in HA aber munter weiterleben. Das hätte schon vor einem Jahr aufgeräumt werden müssen &amp;#x1f601;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Beispiel: alte YAML lesen, ohne den Verstand zu verlieren
&lt;div id="beispiel-alte-yaml-lesen-ohne-den-verstand-zu-verlieren" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#beispiel-alte-yaml-lesen-ohne-den-verstand-zu-verlieren" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Hier wird es richtig interessant, denn hier spielen die großen Kontextfenster moderner KI-Modelle ihre Stärke aus. Ich habe Claude zum Beispiel gefragt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;„Such mir alle Automationen, die &lt;code&gt;light.arbeitszimmer_tischlampe&lt;/code&gt; referenzieren.&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Welche meiner Automationen verwenden denselben Trigger?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Bau mir die YAML für: ‚Heizung im Bad dimmen, wenn keiner zuhause und Fenster auf&amp;rsquo; - aber prüf vorher, ob das mit meinen bestehenden Heizungs-Automationen kollidiert.&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ein wichtiger Punkt für mich: &lt;strong&gt;die Kontrolle bleibt bei mir.&lt;/strong&gt; Claude produziert YAML, ich lese sie, ich übernehme sie. Niemand schreibt &lt;strong&gt;ohne meine Zustimmung&lt;/strong&gt; in mein Setup. Aber das mühsame &lt;em&gt;Lesen und Querverknüpfen&lt;/em&gt; meiner über die Jahre gewachsenen Konfiguration - das übernimmt die KI für mich. Und genau das ist der &lt;strong&gt;langweilige Teil der Refactoring-Arbeit&lt;/strong&gt;, der mich sonst immer wieder davon abhält, &lt;strong&gt;überhaupt anzufangen&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Beispiel: Fragen ans eigene Haus
&lt;div id="beispiel-fragen-ans-eigene-haus" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#beispiel-fragen-ans-eigene-haus" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Das Energy-Panel in &lt;em&gt;Home Assistant&lt;/em&gt; ist gut. Wirklich. Aber alles, was über &lt;em&gt;Verbrauch pro Tag pro Gerät&lt;/em&gt; hinausgeht, ist erstaunlich mühsam. Über MCP fühlt sich das auf einmal &lt;strong&gt;leichtgewichtig&lt;/strong&gt; an:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;„Wann war mein Standby-Verbrauch in den letzten 30 Tagen am höchsten - und welches Gerät war&amp;rsquo;s?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Wie korreliert mein Heizverbrauch mit der Außentemperatur?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Wann ist die Spülmaschine üblicherweise fertig, und wie spät kann ich sie noch starten, damit sie vor 22 Uhr durch ist?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Das sind &lt;strong&gt;Ad-hoc-Auswertungen&lt;/strong&gt;, für die ich mir nie ein eigenes Dashboard bauen würde. Zu spezifisch, zu einmalig. Aber einfach mal eben zu fragen - das ist ein echter Komfortgewinn. Und manchmal lernt man dabei &lt;strong&gt;überraschend viel über sein eigenes Zuhause&lt;/strong&gt; &amp;#x1f604;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Beispiel: endlich Doku, die niemand schreiben wollte
&lt;div id="beispiel-endlich-doku-die-niemand-schreiben-wollte" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#beispiel-endlich-doku-die-niemand-schreiben-wollte" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Das ist meiner Meinung nach der &lt;strong&gt;am meisten unterschätzte&lt;/strong&gt; Anwendungsfall. Ein paar Beispiele für Dinge, die ich mir habe generieren lassen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Eine &lt;strong&gt;Kurzanleitung für meine Frau und Gäste&lt;/strong&gt;, wie unser Smart Home morgens, abends und im Urlaub funktioniert - inklusive der wichtigsten Sprachbefehle für &lt;em&gt;Alexa&lt;/em&gt;. Stichwort: &lt;strong&gt;Women Acceptance Factor&lt;/strong&gt; &amp;#x1f601;.&lt;/li&gt;
&lt;li&gt;Ein &lt;strong&gt;Runbook&lt;/strong&gt; &lt;em&gt;„was tun, wenn die Heizung in einem Raum nicht heizt&amp;quot;&lt;/em&gt; - mit den richtigen Entity-IDs, einem Diagnose-Pfad und den drei häufigsten Ursachen.&lt;/li&gt;
&lt;li&gt;Eine &lt;strong&gt;Architekturskizze&lt;/strong&gt; meines Setups, halbwegs in &lt;a href="https://arc42.org" target="_blank" rel="noopener noreferrer"&gt;arc42 &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;-Logik. Sehr nützlich, wenn ich in zwei Jahren wieder vergessen habe, warum ich Automation Nr. 47 damals gebaut habe.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Natürlich ist die generierte Doku bei dieser Größenordnung &lt;strong&gt;nicht perfekt&lt;/strong&gt; und braucht Nachbearbeitung. Aber sie nimmt mir den Sprung von &amp;ldquo;leeres Dokument&amp;rdquo; zu &amp;ldquo;erster Entwurf&amp;rdquo; ab. Und das ist meistens der Punkt, an dem ich sonst aufschiebe.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Beispiel: wenn das Haus sich seltsam verhält
&lt;div id="beispiel-wenn-das-haus-sich-seltsam-verhält" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#beispiel-wenn-das-haus-sich-seltsam-verh%c3%a4lt" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Der spannendste Use-Case, weil hier die &lt;strong&gt;Mustererkennung&lt;/strong&gt; tatsächlich etwas tut, das ich von Hand so nicht hinbekomme. Meine Idee: einmal pro Woche - als &lt;em&gt;Scheduled Task&lt;/em&gt; - läuft ein Audit-Lauf mit Fragen wie:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;„Sinkt eine Batterie schneller als gewöhnlich?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Läuft ein Gerät länger als sonst?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Wurde eine Automation seltsam oft ausgelöst?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;„Steigt mein Standby-Verbrauch schleichend?&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Home Assistant&lt;/em&gt; selbst hat dafür keine eingebaute Logik. Es gibt einzelne Integrationen, aber nichts, was über mehrere Datenquellen hinweg &lt;strong&gt;korreliert&lt;/strong&gt;. Hier ist das &lt;strong&gt;Reasoning eines Sprachmodells&lt;/strong&gt; ein &lt;strong&gt;guter Fit&lt;/strong&gt; - nicht perfekt, aber gut genug, um mich auf Dinge hinzuweisen, die ich sonst übersehen hätte. Und mehr will ich auch gar nicht.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Stolpersteine und Grenzen
&lt;div id="stolpersteine-und-grenzen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#stolpersteine-und-grenzen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Damit der Beitrag nicht klingt wie eine Werbeanzeige, hier noch ein &lt;strong&gt;paar Beobachtungen&lt;/strong&gt; aus den letzten Tagen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kontextfenster sind nicht unendlich.&lt;/strong&gt; Bei meinen ganzen Entitäten passt nicht alles in einen Prompt. Gute MCP-Server arbeiten daher mit &lt;strong&gt;gezielten Abfragen&lt;/strong&gt; - Claude sagt nicht &lt;em&gt;„zeig mir alles&amp;quot;&lt;/em&gt;, sondern fragt &lt;em&gt;erst&lt;/em&gt; nach Bereichen, &lt;em&gt;dann&lt;/em&gt; nach Entitäten, &lt;em&gt;dann&lt;/em&gt; nach Details. Das funktioniert, kostet aber gelegentlich eine Nachfrage mehr.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Halluzinationen gibt es.&lt;/strong&gt; Ich habe von Claude schon Entity-IDs vorgeschlagen bekommen, die es so gar nicht gibt. Lösung ist banal: &lt;strong&gt;niemals ungeprüft übernehmen&lt;/strong&gt;. Jede generierte Automation wird von mir in der HA-UI durchgeklickt, bevor sie scharf geht. Und dann gäbe es ja noch &lt;a href="https://spook.boo" target="_blank" rel="noopener noreferrer"&gt;Spook &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;, der uns vor falschen Benamungen schützt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schnell ist anders.&lt;/strong&gt; Ein vollständiger Audit-Lauf über alle Integrationen dauert mehrere Minuten. Das ist okay, wenn du es einmal pro Woche machst - aber &lt;strong&gt;nicht&lt;/strong&gt;, wenn du interaktiv arbeiten willst.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Berechtigungen in HA sind flach.&lt;/strong&gt; &lt;em&gt;Home Assistant&lt;/em&gt; kennt nur &lt;strong&gt;Admin&lt;/strong&gt; oder &lt;strong&gt;Non-Admin&lt;/strong&gt;, echtes Rollen- und Rechtemanagement gibt es nicht. Ein dediziertes Token allein schützt also nicht davor, dass Claude über die API erstaunlich viel anfassen kann. Eine &lt;strong&gt;entity-spezifische Filterung pro Benutzer&lt;/strong&gt; kennt HA ebenfalls nicht. Was übrig bleibt, ist im Wesentlichen der Approval-Modus in &lt;em&gt;Claude Desktop&lt;/em&gt;. Mehr dazu gleich.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Datenschutz braucht Disziplin.&lt;/strong&gt; Auch wenn &lt;em&gt;ha-mcp&lt;/em&gt; lokal läuft: was Claude liest, geht zur Verarbeitung an Anthropic. Das ist kein klassischer &lt;strong&gt;Cloudzwang&lt;/strong&gt;, aber eben auch nicht der reine Lokalbetrieb.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="warning"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Warning
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Wer ein Setup mit besonders sensiblen Bereichen hat (Kinderzimmer, Pflegesituationen, medizinische Sensorik), sollte sich vor dem Einsatz von Cloud-KI gut überlegen, &lt;em&gt;ob&lt;/em&gt; er an dieser Stelle mit KI arbeiten möchte.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Zwei Maßnahmen, mit denen ich das Risiko klein halte
&lt;div id="zwei-maßnahmen-mit-denen-ich-das-risiko-klein-halte" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#zwei-ma%c3%9fnahmen-mit-denen-ich-das-risiko-klein-halte" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wie eben angerissen: echtes Rollen- und Rechtemanagement bietet &lt;em&gt;Home Assistant&lt;/em&gt; nicht, und &lt;em&gt;Claude Desktop&lt;/em&gt; hat (Stand heute) auch noch keinen Schalter, um einzelne Tools eines MCP-Servers individuell abzuklemmen. Was übrig bleibt, sind zwei pragmatische Riegel, auf die ich mich verlasse:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Dedizierter Non-Admin-User in HA.&lt;/strong&gt; Claude bekommt ein &lt;strong&gt;Long-Lived Access Token&lt;/strong&gt; über einen &lt;strong&gt;eigenen Benutzer ohne Admin-Rechte&lt;/strong&gt;. Damit fällt zumindest der direkte Zugriff auf die Konfigurationsdateien raus. Eine echte Entity-Filterung pro Benutzer kennt HA leider nicht. Was der User darf, das sieht er.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Approval-Modus konsequent anlassen.&lt;/strong&gt; &lt;em&gt;Claude Desktop&lt;/em&gt; fragt per Default vor jedem Tool-Aufruf nach. Genau diese Bestätigung ist meine wichtigste Sicherheitsschicht, denn alles, was die KI auslösen könnte, läuft erst nach meinem aktiven Klick. Beim ersten Ausprobieren etwas nervig, im Alltag aber Gold wert.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Immerhin ein kleines Plus serverseitig: &lt;em&gt;ha-mcp&lt;/em&gt; lässt &lt;strong&gt;direkte YAML-Edits&lt;/strong&gt; standardmäßig &lt;strong&gt;nicht zu&lt;/strong&gt; (&lt;code&gt;ENABLE_YAML_CONFIG_EDITING=false&lt;/code&gt;). Wer das nicht aktiv anschaltet, hat zumindest diese Klasse von Schreibzugriffen schon mal ausgeschlossen.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Was sich für mich verändert hat
&lt;div id="was-sich-für-mich-verändert-hat" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-sich-f%c3%bcr-mich-ver%c3%a4ndert-hat" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Drei konkrete Dinge; und das nach gerade mal einer Woche.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Erstens: ich räume tatsächlich auf.&lt;/strong&gt; Was vorher ein halber Samstag war, ist jetzt eine &lt;strong&gt;halbe Stunde am Sonntagabend&lt;/strong&gt;. Und damit passiert es auch wirklich.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Zweitens: ich traue mich an Refactorings.&lt;/strong&gt; Dinge, vor denen ich mich gedrückt habe - &lt;em&gt;„dieser ganze Lichter-Block ist über die Jahre Mist geworden, aber neu schreiben dauert ewig&amp;quot;&lt;/em&gt; - sind plötzlich machbar, weil das mühsame Lesen abgenommen wird.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Drittens: ich verstehe mein eigenes Setup besser.&lt;/strong&gt; Klingt komisch, ist aber so. Wenn ich Claude bitte, mir die &lt;em&gt;Lichtsteuerung im Flur&lt;/em&gt; zu erklären, bekomme ich eine Zusammenfassung, die mir &lt;strong&gt;selbst Lücken&lt;/strong&gt; in meinen Annahmen aufzeigt. Sehr spannend &amp;#x1f601;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;MCP ist für mich kein &lt;em&gt;Killer-Feature&lt;/em&gt;, das mein Smart Home revolutioniert. Niemand muss heute panisch loslegen, nur weil es gerade ein Trendthema ist. Aber für ein &lt;strong&gt;gewachsenes, gepflegtes Setup&lt;/strong&gt; ist es ein &lt;strong&gt;erstaunlich nützliches Werkzeug&lt;/strong&gt; - und zwar genau dort, wo die manuelle Arbeit am wenigsten Spaß macht: bei der &lt;strong&gt;Hygiene&lt;/strong&gt;, beim &lt;strong&gt;Lesen alter Konfiguration&lt;/strong&gt;, bei der &lt;strong&gt;ad-hoc-Datenanalyse&lt;/strong&gt;, bei der &lt;strong&gt;Dokumentation&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Was es &lt;strong&gt;nicht&lt;/strong&gt; ist: ein Ersatz für &lt;em&gt;Verstehen&lt;/em&gt;. Claude weiß nicht, &lt;strong&gt;warum&lt;/strong&gt; meine Heizungs-Boost-Logik so aussieht, wie sie aussieht. Ich weiß es. Und genau dieses Verständnis braucht es, um die Vorschläge der KI &lt;strong&gt;bewerten&lt;/strong&gt; zu können.&lt;/p&gt;
&lt;p&gt;Ich glaube, das ist die wichtigste Erkenntnis aus den letzten Tagen: &lt;strong&gt;MCP ist ein Lesegerät und ein Skizzenblock, kein Architekt.&lt;/strong&gt; Architekt bleibt weiterhin &lt;strong&gt;wer auch immer das Setup gebaut hat - also wir selbst.&lt;/strong&gt; Und ehrlich gesagt: das ist genau richtig so.&lt;/p&gt;
&lt;p&gt;Zumindest noch &amp;#x1f604;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wie sieht das bei dir aus?&lt;/strong&gt; Hast du schon mit MCP herumgespielt, oder bist du noch am Beobachten? Schreib mir gern.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@growtika?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Growtika &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/ein-abstraktes-bild-einer-kugel-mit-punkten-und-linien-nGoCBxiaRO0?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;HACS steht für &lt;em&gt;Home Assistant Community Store&lt;/em&gt; und ist der inoffizielle Marktplatz für Integrationen, Themes und Add-ons, die nicht direkt in &lt;em&gt;Home Assistant&lt;/em&gt; enthalten sind. Siehe &lt;a href="https://hacs.xyz" target="_blank" rel="noopener noreferrer"&gt;hacs.xyz &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Ein langlebiger Zugangs-Token aus &lt;em&gt;Home Assistant&lt;/em&gt;, mit dem sich externe Tools gegenüber der HA-API authentifizieren - die saubere Alternative zur klassischen Benutzername/Passwort-Kombi.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry><entry><title>pypaperless v6 - Und wieder ein Reboot</title><link href="https://tbsch.de/post/2026-04-01-pypaperless-v6-und-wieder-ein-reboot/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2026-04-01-pypaperless-v6-und-wieder-ein-reboot/</id><published>2026-04-01T00:00:00Z</published><updated>2026-04-01T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="news"/><category term="paperless"/><category term="projekt"/><category term="python"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2026-04-01-pypaperless-v6-und-wieder-ein-reboot/featured.webp"/><summary type="html">pypaperless v6 erscheint kurz nach Paperless-ngx v3 und bringt Breaking Changes. Ein Blick hinter die Kulissen.</summary><content type="html">&lt;p&gt;Kurz nach dem Release von &lt;em&gt;Paperless-ngx&lt;/em&gt; v3 folgt &lt;em&gt;pypaperless&lt;/em&gt; v6 - und diesmal hat es wirklich Konsequenzen. Aufgrund vielerlei Veränderungen in der &lt;em&gt;Paperless-ngx&lt;/em&gt; REST API und meinem Unwillen, bis in alle Ewigkeit rückwärts-kompatibel zu sein, traf ich eine Entscheidung. Es gibt Breaking Changes. Und damit meine ich nicht „eine Methode wurde umbenannt“, sondern einen tiefgreifenden Umbau der gesamten Bibliothek.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Warum ein Reboot?
&lt;div id="warum-ein-reboot" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#warum-ein-reboot" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wenn ich ehrlich bin, hatte &lt;em&gt;pypaperless&lt;/em&gt; in v5 drei Baustellen, über die ich schon länger immer wieder gestolpert bin. Alle drei haben mich genug gestört, um diesmal wirklich von Grund auf neu zu bauen. Und in diesem Anlauf habe ich mein aktuelles Verständnis von SDK-Gedanken noch mehr einfließen lassen.&lt;/p&gt;
&lt;h3 class="relative group"&gt;1. Models waren zu eng ans HTTP-Layer gekoppelt
&lt;div id="1-models-waren-zu-eng-ans-http-layer-gekoppelt" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#1-models-waren-zu-eng-ans-http-layer-gekoppelt" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;In v5 hielt jede Model-Instanz eine Referenz auf den Client und rief ihn intern direkt auf. Das klingt praktisch, führt aber dazu, dass man Models nicht isoliert testen kann und sie auch nicht ohne Kontext weitergeben kann. Das war beim Testen regelmäßig ein Ärgernis.&lt;/p&gt;
&lt;p&gt;In v6 sind Models reine Daten - kein Client, keine HTTP-Aufrufe. Der gesamte I/O läuft ausschließlich über Services. Das macht den Code deutlich sauberer und testbarer. &lt;strong&gt;Und als kleines Schmankerl&lt;/strong&gt; habe ich einen kleinen Dispatcher in die &lt;code&gt;PaperlessClient&lt;/code&gt; Klasse eingebaut, über den wichtige CRUD-Methoden direkt nutzbar sind.&lt;/p&gt;
&lt;div
class="tab__container w-full"
&gt;
&lt;div class="tab__nav" role="tablist"&gt;
&lt;div class="flex flex-wrap gap-1"&gt;&lt;button
class="tab__button px-3 py-2 text-sm font-semibold border-b-2 border-transparent rounded-t-md hover:bg-neutral-200 dark:hover:bg-neutral-700 tab--active"
role="tab"
aria-selected="true"
data-tab-index="0"
data-tab-label="Vorher (v5)"&gt;
&lt;span class="flex items-center gap-1"&gt;
Vorher (v5)
&lt;/span&gt;
&lt;/button&gt;&lt;button
class="tab__button px-3 py-2 text-sm font-semibold border-b-2 border-transparent rounded-t-md hover:bg-neutral-200 dark:hover:bg-neutral-700 "
role="tab"
aria-selected="false"
data-tab-index="1"
data-tab-label="Nachher (v6)"&gt;
&lt;span class="flex items-center gap-1"&gt;
Nachher (v6)
&lt;/span&gt;
&lt;/button&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="tab__content mt-4"&gt;&lt;div class="tab__panel tab--active" data-tab-index="0"&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;doc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; paperless&lt;span style="color:#f92672"&gt;.&lt;/span&gt;documents(&lt;span style="color:#ae81ff"&gt;4711&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;doc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;title &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Ein neuer Titel&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; doc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;save()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="tab__panel " data-tab-index="1"&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;doc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; paperless&lt;span style="color:#f92672"&gt;.&lt;/span&gt;documents(&lt;span style="color:#ae81ff"&gt;4711&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;doc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;title &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Ein neuer Titel&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; paperless&lt;span style="color:#f92672"&gt;.&lt;/span&gt;save(doc)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="relative group"&gt;2. Keine Typprüfung zur Laufzeit
&lt;div id="2-keine-typprüfung-zur-laufzeit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#2-keine-typpr%c3%bcfung-zur-laufzeit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;v5 nutzte Dataclasses mit manueller Dict-Konvertierung. Wenn die API unerwartet etwas zurückgab, konnte das jedoch still und heimlich zu falschen Werten führen. Es gab zwar eine Warning in der Konsole, aber das war&amp;rsquo;s &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;v6 setzt auf &lt;strong&gt;Pydantic v2&lt;/strong&gt;: Jede API-Antwort wird beim Parsen validiert. Ich muss keinem Python-Entwickler die Vorteile davon erklären.&lt;/p&gt;
&lt;h3 class="relative group"&gt;3. aiohttp raus, httpx rein
&lt;div id="3-aiohttp-raus-httpx-rein" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#3-aiohttp-raus-httpx-rein" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;aiohttp&lt;/code&gt; hat seinen Job getan, aber &lt;code&gt;httpx&lt;/code&gt; ist moderner, hat eine sauberere API für synchrone und asynchrone Nutzung, und bringt ein eingebautes Mock-Transport-System mit, das das Schreiben von Tests erheblich vereinfacht. Ein Wechsel, der sich auch beim Entwickeln sofort bemerkbar macht.&lt;/p&gt;
&lt;p&gt;Als User von &lt;em&gt;pypaperless&lt;/em&gt; solltest du diesen Change in den meisten Fällen gar nicht bemerken.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Was ändert sich konkret?
&lt;div id="was-ändert-sich-konkret" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-%c3%a4ndert-sich-konkret" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Die vollständige Checkliste der Breaking Changes gibt es im &lt;a href="https://pypaperless.docs.tbsch.de/migrating-v5-to-v6/" target="_blank" rel="noopener noreferrer"&gt;Migrationsleitfaden &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;, hier die wichtigsten Punkte:&lt;/p&gt;
&lt;h3 class="relative group"&gt;Python 3.13 ist jetzt Pflicht
&lt;div id="python-313-ist-jetzt-pflicht" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#python-313-ist-jetzt-pflicht" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Wer noch auf &amp;lt;=3.12 läuft, muss vor dem Update die Python-Runtime upgraden.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Neues &lt;code&gt;PaperlessConfig&lt;/code&gt;-Objekt und Umgebungsvariablen
&lt;div id="neues-paperlessconfig-objekt-und-umgebungsvariablen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#neues-paperlessconfig-objekt-und-umgebungsvariablen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Der Konstruktor hat sich verändert. Neu ist außerdem die &lt;code&gt;PaperlessConfig&lt;/code&gt;-Klasse:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; pypaperless &lt;span style="color:#f92672"&gt;import&lt;/span&gt; Paperless, PaperlessConfig
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Via Config-Objekt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cfg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; PaperlessConfig(url&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;http://localhost:8000&amp;#34;&lt;/span&gt;, token&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;mytoken&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;paperless &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Paperless(config&lt;span style="color:#f92672"&gt;=&lt;/span&gt;cfg)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Via Umgebungsvariablen (PYPAPERLESS_URL, PYPAPERLESS_TOKEN)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;paperless &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Paperless()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;&lt;code&gt;filter()&lt;/code&gt; statt &lt;code&gt;reduce()&lt;/code&gt;
&lt;div id="filter-statt-reduce" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#filter-statt-reduce" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;reduce()&lt;/code&gt; ist weg. Das neue &lt;code&gt;filter()&lt;/code&gt; funktioniert ähnlich, aber die Context-Manager-Variable ist jetzt das eigentliche Iterationsobjekt:&lt;/p&gt;
&lt;div
class="tab__container w-full"
&gt;
&lt;div class="tab__nav" role="tablist"&gt;
&lt;div class="flex flex-wrap gap-1"&gt;&lt;button
class="tab__button px-3 py-2 text-sm font-semibold border-b-2 border-transparent rounded-t-md hover:bg-neutral-200 dark:hover:bg-neutral-700 tab--active"
role="tab"
aria-selected="true"
data-tab-index="0"
data-tab-label="Vorher (v5)"&gt;
&lt;span class="flex items-center gap-1"&gt;
Vorher (v5)
&lt;/span&gt;
&lt;/button&gt;&lt;button
class="tab__button px-3 py-2 text-sm font-semibold border-b-2 border-transparent rounded-t-md hover:bg-neutral-200 dark:hover:bg-neutral-700 "
role="tab"
aria-selected="false"
data-tab-index="1"
data-tab-label="Nachher (v6)"&gt;
&lt;span class="flex items-center gap-1"&gt;
Nachher (v6)
&lt;/span&gt;
&lt;/button&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="tab__content mt-4"&gt;&lt;div class="tab__panel tab--active" data-tab-index="0"&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;filters &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;title__icontains&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;invoice&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; paperless&lt;span style="color:#f92672"&gt;.&lt;/span&gt;documents&lt;span style="color:#f92672"&gt;.&lt;/span&gt;reduce(&lt;span style="color:#f92672"&gt;**&lt;/span&gt;filters):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; doc &lt;span style="color:#f92672"&gt;in&lt;/span&gt; paperless&lt;span style="color:#f92672"&gt;.&lt;/span&gt;documents:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(doc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;title)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="tab__panel " data-tab-index="1"&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;filters &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;title__icontains&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;invoice&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; paperless&lt;span style="color:#f92672"&gt;.&lt;/span&gt;documents&lt;span style="color:#f92672"&gt;.&lt;/span&gt;filter(&lt;span style="color:#f92672"&gt;**&lt;/span&gt;filters) &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; ctx:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; doc &lt;span style="color:#f92672"&gt;in&lt;/span&gt; ctx:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(doc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;title)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="relative group"&gt;Erstellen neuer Models
&lt;div id="erstellen-neuer-models" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#erstellen-neuer-models" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;draft()&lt;/code&gt; heißt jetzt &lt;code&gt;create()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Was ist neu?
&lt;div id="was-ist-neu" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-ist-neu" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Neben dem Umbau kommen sechs neue Services dazu:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;paperless.profile&lt;/code&gt;&lt;/strong&gt; - Zugriff auf das eigene Benutzerprofil&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;paperless.trash&lt;/code&gt;&lt;/strong&gt; - Gelöschte Dokumente durchsuchen, wiederherstellen oder den Papierkorb leeren&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;paperless.share_links&lt;/code&gt;&lt;/strong&gt; - Share-Links für Dokumente erstellen und verwalten&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;paperless.documents.history&lt;/code&gt;&lt;/strong&gt; - Audit-Log eines Dokuments abrufen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;paperless.documents.bulk_edit&lt;/code&gt;&lt;/strong&gt; - Massenoperationen auf vielen Dokumenten in einem einzigen API-Aufruf&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;paperless.bulk_edit_objects&lt;/code&gt;&lt;/strong&gt; - Berechtigungen oder Löschvorgänge auf Tags, Korrespondenten, Dokumenttypen und Speicherpfaden in Massen&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;v6 ist kein kleines Pflaster. Ich bin mit den Neuerungen und Änderungen sehr glücklich. Der Preis dafür ist eine Migration, die für bestehende User etwas Arbeit bedeutet.&lt;/p&gt;
&lt;p&gt;Der &lt;a href="https://pypaperless.docs.tbsch.de/migrating-v5-to-v6/" target="_blank" rel="noopener noreferrer"&gt;Migrationsleitfaden &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; führt Schritt für Schritt durch alle Änderungen.&lt;/p&gt;
&lt;p&gt;Viel Spaß mit &lt;em&gt;pypaperless&lt;/em&gt; v6!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@cdr6934?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Chris Ried &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/ein-computerbildschirm-mit-einem-haufen-code-darauf-ieic5Tq8YMk?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Meine Seite ist zurück!</title><link href="https://tbsch.de/post/2026-03-06-meine-seite-ist-zur%C3%BCck/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2026-03-06-meine-seite-ist-zur%C3%BCck/</id><published>2026-03-06T00:00:00Z</published><updated>2026-03-06T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="urlaub"/><category term="familie"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2026-03-06-meine-seite-ist-zur%C3%BCck/featured.webp"/><summary type="html">Mein Elternurlaub ist vorbei, demnach werde ich bald wieder neue Beiträge veröffentlichen.</summary><content type="html">&lt;div class="lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl"&gt;
Das Leben wird vorwärts gelebt und rückwärts verstanden.
&lt;/div&gt;
&lt;p&gt;Treffender hätte es &lt;em&gt;Kierkegaard&lt;/em&gt; wohl nicht formulieren können. Am Anfang ist da diese eine Nachricht: wir erwarten ein Kind. Ich glaube, so wirklich verstehen wird das niemand, was da gerade passiert, &lt;strong&gt;bis&lt;/strong&gt; es dann passiert ist.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Wieder da
&lt;div id="wieder-da" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#wieder-da" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Diese eine verschneite Winternacht hat mein Leben auf einen Schlag geändert: plötzlich ist da ein kleiner Mensch. Der hat vollkommen andere Bedürfnisse und Erwartungen an seine Umgebung. Es hat mir gezeigt, wie schlecht auch mein Smart Home eigentlich auf ein kleines Kind abgestimmt war. Nun, das war ja bislang auch nicht notwendig &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;Glücklicherweise hatte ich in der Vergangenheit in der Licht- und Heizungssteuerung die Möglichkeit eingebaut, die Automatisierungen manuell zu überschreiben - so konnten wir zumindest darauf einwirken.&lt;/p&gt;
&lt;p&gt;Ein kleines Beispiel gefällig? Abends erstrahlt das Wohnzimmer in wechselnden bunten Farben, beim TV-Schauen wird das Licht automatisch gedimmt. Wenn da allerdings ein kleines Baby ist, welches gerade einschlafen soll, möchte man grundsätzlich gedimmtes Licht haben und nicht nur dann, wenn der TV eingeschaltet ist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Übrigens:&lt;/strong&gt; ich arbeite gegenwärtig noch daran, eure E-Mails zu beantworten. Einige Antworten habe ich bereits verschickt, etwa ein Dutzend warten noch. Entschuldigt bitte!&lt;/p&gt;
&lt;h2 class="relative group"&gt;Tech News
&lt;div id="tech-news" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#tech-news" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Der März wird sehr spannend: es steht ein großes Update meiner &lt;a href="/home-lab/#mikrotik-hap-ax3"&gt;MikroTik&lt;/a&gt; Generation an. Die Letten haben es endlich fertiggebracht, die &lt;strong&gt;hAP&lt;/strong&gt;-Serie um wenigstens Wifi7 zu erweitern. Demnach flattern Mitte März drei brandneue &lt;strong&gt;&lt;a href="https://mikrotik.com/product/hap_be3_media" target="_blank" rel="noopener noreferrer"&gt;MikroTik hAP be3 Media &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; in meinen Briefkasten!&lt;/p&gt;
&lt;p&gt;Ich freue mich schon sehr darauf, das gesamte Heimnetzwerk auf das nächste Level zu heben. Neben Wifi7 gibt es dann auch durchweg 2.5G LAN im ganzen Haus - auf allen drei Stockwerken. Die dafür notwendige Arbeit ist größtenteils seit Mitte letzten Jahres erledigt, denn ich habe für alle drei Geräte bereits die Configs erstellt und muss sie nur noch einspielen.&lt;/p&gt;
&lt;p&gt;RouterOS sei Dank &amp;#x1f604;!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@ryanstefan?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Ryan Stefan &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/braunes-betonpflaster-9jDaQIeTXkc?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Meine Seite verabschiedet sich in den Urlaub</title><link href="https://tbsch.de/post/2025-12-19-meine-seite-verabschiedet-sich-in-den-urlaub/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2025-12-19-meine-seite-verabschiedet-sich-in-den-urlaub/</id><published>2025-12-19T00:00:00Z</published><updated>2025-12-19T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="urlaub"/><category term="familie"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2025-12-19-meine-seite-verabschiedet-sich-in-den-urlaub/featured.webp"/><summary type="html">Im neuen Jahr steht eine Menge an, weshalb ich vorerst keine Beiträge veröffentlichen werde.</summary><content type="html">&lt;p&gt;Ja, du hast richtig gelesen: vorerst werde ich keine Beiträge mehr verfassen. Aber nicht für immer &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;Das liegt nicht daran, dass Technik mich nicht mehr begeistert - ganz im Gegenteil. Ich werde viele coole neue Ideen entwickeln und auf jeden Fall hier darüber berichten. Doch zuvor steht nun die Weihnachtszeit an - jeden Tag des Fests bin ich unterwegs und schlage mir bei Familie und Freunden den Bauch voll. Geil!&lt;/p&gt;
&lt;p&gt;Allerdings schicke ich meine Webseite jetzt erst einmal in Elternzeit. In Zukunft werde ich unser Smart Home nicht mehr ausschließlich nach dem &lt;strong&gt;Women Acceptance Factor&lt;/strong&gt; designen, sondern auch den Nachwuchs in der Architektur berücksichtigen müssen. Ich werde bald darüber berichten, wie gut oder schlecht mir dies gelingen wird &amp;#x1f604;.&lt;/p&gt;
&lt;p&gt;Bis dahin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@ryanstefan?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Ryan Stefan &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/braunes-betonpflaster-9jDaQIeTXkc?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Paperless Guide: Secretary Bot</title><link href="https://tbsch.de/post/2025-12-18-paperless-guide-secretary/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2025-12-18-paperless-guide-secretary/</id><published>2025-12-18T00:00:00Z</published><updated>2025-12-18T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="home-lab"/><category term="guide"/><category term="paperless"/><category term="python"/><category term="workflow"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2025-12-18-paperless-guide-secretary/featured.webp"/><summary type="html">Das papierlose Büro mit Scripting automatisieren und effizienter machen.</summary><content type="html">&lt;p&gt;Es ist eine Weile her, seit ich zuletzt über mein papierloses Büro geschrieben habe. Denn mein System läuft und tut genau das, was es soll - seit nunmehr vielen Jahren. In der Zwischenzeit gab es jedoch zahlreiche Neuerungen bei &lt;em&gt;Paperless-ngx&lt;/em&gt;, wie zum Beispiel die Arbeitsabläufe (Workflows) mit Webhooks und &lt;em&gt;Nested Tags&lt;/em&gt;. Gerade &lt;strong&gt;Webhooks&lt;/strong&gt; sind für mich enorm interessant, weil sie bei neuen, geänderten und gelöschten Dokumenten auslösen können.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Integration anderer Dienste
&lt;div id="integration-anderer-dienste" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#integration-anderer-dienste" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Mit Webhooks ist es endlich möglich, &lt;em&gt;Paperless-ngx&lt;/em&gt; mit anderen Diensten zu verbinden. Gerade weil sie auch bei einem Update von Dokumenten auslösen können, lösten sie direkt meine &lt;strong&gt;Pre- und Post-Consume-Skripte&lt;/strong&gt; ab. Diese setzte ich ein, um sehr einfach gestrickte Validierungen laufen zu lassen.&lt;/p&gt;
&lt;p&gt;Diese neue Situation nahm ich mir zum Anlass, um meinen &lt;strong&gt;&lt;a href="/post/2024-08-28-paperless-guide-customization/#paperless-secretary"&gt;Paperless Secretary&lt;/a&gt;&lt;/strong&gt; neu aufzubauen. Bislang handelte es sich hierbei um ein einfaches Python Skript, in dem ich Dokumenten-Filter und Aktionen definiert hatte. In den letzten Wochen ist ein kleiner Webservice entstanden, der als Docker-Container bereitgestellt wird und - wer hätte es geahnt - auf HTTP-Anfragen wartet. Wie eben jene von den neuen &lt;em&gt;Paperless-ngx&lt;/em&gt; Webhooks &amp;#x1f601;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Secretary v2
&lt;div id="secretary-v2" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#secretary-v2" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Der neue &lt;strong&gt;Paperless Secretary&lt;/strong&gt; besteht aus zwei Bausteinen: dem Webservice, der die Anfragen entgegennimmt. Und der &lt;em&gt;Rules Engine&lt;/em&gt;, die konfigurierte Regelwerke aus Konfigurationsdateien liest, validiert und ausführt.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Verfügbarkeit
&lt;div id="verfügbarkeit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#verf%c3%bcgbarkeit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Source Code und Dokumentation stehen zum aktuellen Zeitpunkt &lt;strong&gt;nicht&lt;/strong&gt; öffentlich zur Verfügung, da das Projekt noch sehr frisch ist und ich auf absehbare Zeit keinen Support leisten kann. Dennoch möchte ich die Gelegenheit nutzen und dir zeigen, wie man solche Webhooks einsetzen könnte.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Ich werde in den nächsten Monaten an genau &lt;strong&gt;dieser&lt;/strong&gt; Stelle das Container Image veröffentlichen. Und zwar dann, wenn ich die Dokumentation auf Vordermann gebracht habe.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;Regelwerke
&lt;div id="regelwerke" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#regelwerke" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Der &lt;strong&gt;Secretary&lt;/strong&gt; hält ein Verzeichnis aus YAML Dateien, in denen komplexe Regeln vorgegeben werden können. Verwendest du &lt;a href="https://www.home-assistant.io" target="_blank" rel="noopener noreferrer"&gt;Home Assistant &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;? Dann ist dir das Konzept sicher geläufig, denn ich habe mich beim Design der Regel-Notationen stark von &lt;em&gt;Home Assistant Automationen&lt;/em&gt; inspirieren lassen. Denn eine Sache haben die Schöpfer vollkommen richtig gemacht: du kannst auf einen Blick herauslesen, was die Automation machen soll. Und genau das wollte ich für Regeln auch.&lt;/p&gt;
&lt;p&gt;Eine Secretary Regel besteht immer aus ihrer Bezeichnung, Bedingungen (&lt;code&gt;when&lt;/code&gt;) und Aktionen (&lt;code&gt;exec&lt;/code&gt;). Bedingungen und Aktionen können beliebig viele Filter bzw. Aktionen ausführen. Und das macht es sehr dynamisch und spannend &amp;#x1f60e;.&lt;/p&gt;
&lt;p&gt;Genug Theorie, sehen wir uns so eine Regel doch einfach mal an.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Regel-Kopf und Bedingungen:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;kontoauszug_bank_titel_check&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;description&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Ziel: Titel =&amp;gt; YYYY/MM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;when&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;correspondent&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;N26&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;document_type&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Kontoauszug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;not&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;title&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;regex&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;^20\d{2}/(0[1-9]|1[0-2])$&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;tags&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;contains&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Problem&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Gesucht werden mit dieser Regel Dokumente, deren Korrespondent &lt;em&gt;N26&lt;/em&gt; und Dokument-Typ &lt;em&gt;Kontoauszug&lt;/em&gt; ist, die aber weder den Tag &lt;em&gt;Problem&lt;/em&gt; noch einen Titel im Format &lt;em&gt;YYYY/MM&lt;/em&gt; besitzen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Aktionen anwenden:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;exec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;regex&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;field&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;pattern&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;\d{2}\.(\d{2})\.(\d{4}) bis \d{2}\.\1\.\2&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;result&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ m2 }}/{{ m1 }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;output&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;result_one&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;regex&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;field&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;pattern&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;Depotauszug per \d{2}\.(\d{2})\.(\d{4})&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;result&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ m2 }}/{{ m1 }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;output&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;result_two&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;variable&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;match_result&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {%- if result_one is defined -%}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ result_one }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {%- elif result_two is defined -%}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ result_two }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {%- endif -%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;if&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;when&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;template&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ match_result != &amp;#39;&amp;#39; }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;then&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;set&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ match_result }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;tag_add&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ tag(&amp;#39;Problem&amp;#39;) }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;note&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Der korrekte Titel konnte nicht ermittelt werden.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;save&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Die Aktionen sind - mit Ausnahme der regulären Ausdrücke - eigentlich sofort verständlich. Machen wir dennoch einen kurzen Deep Dive:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Der Inhalt des Dokuments wird nach einem Textmuster abgesucht, welches diese Form hat: &lt;code&gt;00.00.0000 bis 00.00.0000&lt;/code&gt;. Das Ergebnis wird zu &lt;code&gt;0000/00&lt;/code&gt; transformiert und in &lt;code&gt;result_one&lt;/code&gt; gespeichert.&lt;/li&gt;
&lt;li&gt;Erneut wird ein Textmuster mit dieser Form gesucht: &lt;code&gt;Depotauszug per 00.00.0000&lt;/code&gt;. Das Ergebnis wird zu &lt;code&gt;0000/00&lt;/code&gt; transformiert und in &lt;code&gt;result_two&lt;/code&gt; gespeichert.&lt;/li&gt;
&lt;li&gt;In der Variable &lt;code&gt;match_result&lt;/code&gt; wird der Fund eines Textmusters gespeichert.&lt;/li&gt;
&lt;li&gt;Wenn es einen Fund gab, wird der Titel des Dokuments gesetzt.&lt;/li&gt;
&lt;li&gt;Falls es keinen Fund gab, wird der Tag &lt;em&gt;Problem&lt;/em&gt; gesetzt und eine Notiz am Dokument hinterlassen.&lt;/li&gt;
&lt;li&gt;Die Änderungen werden in &lt;em&gt;Paperless-ngx&lt;/em&gt; gespeichert.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Für den Tag &lt;em&gt;Problem&lt;/em&gt; habe ich mich entschieden, da ich etwas manuell nacharbeiten muss. Welche Tags ich wofür verwende, kannst du &lt;a href="https://tbsch.de/post/2024-02-11-paperless-guide-classification/#tagging"&gt;hier&lt;/a&gt; nachlesen.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Warum ich so viel Aufwand betreibe? Die Antwort liegt auf der Hand: ich bin ein fauler Mensch und werde intrinsisch angetrieben, Abläufe zu optimieren und zu automatisieren. Ich müsste viele Dokumente per Hand selbst bearbeiten, damit sie zu meinen Ablagevorstellungen passen - also lasse ich das machen. So einfach ist das &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;Mittlerweile habe ich ein recht großes Regelwerk gebaut und bin unendlich zufrieden damit. Schade, dass in &lt;em&gt;Paperless-ngx&lt;/em&gt; selbst keinerlei Möglichkeiten zur Verfügung stehen, Regelwerke einzubauen. Aber was nicht ist, kann ja schließlich noch werden.&lt;/p&gt;
&lt;p&gt;Welche Use-Cases würdest du automatisiert gern in deinem papierlosen Büro umsetzen? Lass es mich wissen!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@dhruvansh98?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Dhruvansh Soni &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/rotes-und-schwarzes-computer-motherboard-Mo7RooYGXi4?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Der Wahnsinn: warum ich DNS-Blocking verwende</title><link href="https://tbsch.de/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/</id><published>2025-09-23T00:00:00Z</published><updated>2025-09-23T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="home-lab"/><category term="bericht"/><category term="dns"/><category term="privacy"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/featured.webp"/><summary type="html">Nichts ist so kostbar, wie die eigene Privatsphäre. Ein kleiner Bericht über ihren Schutz im Internet.</summary><content type="html">&lt;div class="lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl"&gt;
Privacy is not a crime, protect yourself. Privacy matters. Privacy is what allows us to determine who we are and who we want to be!
&lt;/div&gt;
&lt;p&gt;Diese wahren Worte stammen vom DNS-Blocklisten-Kurator &lt;a href="https://github.com/hagezi/dns-blocklists" target="_blank" rel="noopener noreferrer"&gt;hagezi &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;. Doch was hat es mit &lt;strong&gt;DNS-Blocking&lt;/strong&gt; eigentlich genau auf sich? Und wie genau unterscheidet es sich von einem &lt;strong&gt;Adblocker&lt;/strong&gt;, den du womöglich als Browser-Plugin installiert hast?&lt;/p&gt;
&lt;p&gt;Falls du DNS (Domain Name System) und das Prinzip dahinter noch nicht kennst, lohnt sich ein Blick in den &lt;a href="https://de.wikipedia.org/wiki/Domain_Name_System" target="_blank" rel="noopener noreferrer"&gt;Wikipedia-Artikel &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;. Hier wird es verständlich beschrieben und am Ende bist du um ein Quäntchen &lt;strong&gt;wertvolles Digitalwissen&lt;/strong&gt; reicher &amp;#x1f604;. Du benötigst es außerdem, um die folgenden Absätze nachvollziehen zu können.&lt;/p&gt;
&lt;p&gt;Steigen wir nun etwas tiefer ein: du wirst nun erfahren, wie du dein &lt;strong&gt;heimisches Internetvergnügen&lt;/strong&gt; auf das nächste Level bringen kannst.&lt;/p&gt;
&lt;h2 class="relative group"&gt;DNS-Blocking
&lt;div id="dns-blocking" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dns-blocking" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;h3 class="relative group"&gt;Was ist das?
&lt;div id="was-ist-das" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-ist-das" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Normalerweise fragt jedes Gerät einen DNS-Server: &lt;em&gt;welche IP-Adresse gehört zu dieser Domain?&lt;/em&gt; DNS-Blocking sorgt nun dafür, dass bestimmte Internetadressen gar nicht erst aufgelöst werden. Ohne Antwort gibt es &lt;strong&gt;keine Verbindung&lt;/strong&gt;, weil das Gerät nicht weiß, wohin es sich verbinden soll – so einfach ist das.&lt;/p&gt;
&lt;p&gt;Beim DNS-Blocking prüft der DNS-Server jede Anfrage gegen &lt;em&gt;Blocklisten&lt;/em&gt;. Ist die Domain dort gelistet, gibt es keine gültige Antwort zurück. Damit wird der Inhalt blockiert, bevor er überhaupt aus dem Internet geladen werden kann – und das ist der wesentliche Unterschied zum &lt;strong&gt;Adblocker&lt;/strong&gt;, der &lt;strong&gt;Werbung&lt;/strong&gt; innerhalb deines Browsers einfach nur &lt;strong&gt;ausblendet&lt;/strong&gt;, nachdem sie &lt;strong&gt;bereits geladen&lt;/strong&gt; wurde.&lt;/p&gt;
&lt;p&gt;Der Vorteil im privaten Netzwerk ist der zentrale Ansatz, denn du brauchst keinen &lt;strong&gt;Adblocker&lt;/strong&gt; mehr auf jedem Gerät. Stattdessen profitieren alle deine Endgeräte automatisch, sobald sie den DNS(-Blocking)-Server nutzen.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Auswirkungen
&lt;div id="auswirkungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#auswirkungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Positiv spürbar ist das sofort: &lt;strong&gt;Seiten laden schneller&lt;/strong&gt;, weil unnützer Ballast wegfällt. &lt;strong&gt;Bandbreite wird gespart&lt;/strong&gt;, weil weniger Daten übertragen werden. Und auch die &lt;strong&gt;Sicherheit steigt&lt;/strong&gt;, da Angriffe über fragwürdige Domains ins Leere laufen. Zusätzlich schützt DNS-Blocking deine Privatsphäre, indem Tracker keine Daten mehr abgreifen können.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Zu restriktives DNS-Blocking&lt;/strong&gt; kann jedoch auch dazu führen, dass einige deiner Dienste nicht mehr korrekt funktionieren. Landet eine bekannte Tracking-Domain auf einer DNS-Blockliste, die jedoch gleichzeitig für das Aufrufen von bspw. &lt;em&gt;Instagram&lt;/em&gt; benötigt wird, meldet sich die App bei dir direkt mit &lt;strong&gt;Verbindungsproblemen&lt;/strong&gt; zu Wort.&lt;/p&gt;
&lt;p&gt;Die Kunst beim DNS-Blocking ist also, Werbung, Tracker und Sicherheitsrisiken auszuschließen und gleichzeitig die Funktionsweise deiner alltäglichen Dienste und Apps zu gewährleisten. Und das bedeutet jede Menge Arbeit.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Historische Gründe
&lt;div id="historische-gründe" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#historische-gr%c3%bcnde" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Wir nutzen &lt;strong&gt;Adblocker&lt;/strong&gt; oder &lt;strong&gt;DNS-Blocking&lt;/strong&gt;, weil Werbung im Internet längst nicht mehr nur dezent am Rand steht. Sie ist laut, störend und oft sicherheitskritisch. Pop-ups, Autoplay-Videos und aggressive Banner lenken ab und kosten Bandbreite.&lt;/p&gt;
&lt;p&gt;Gleichzeitig hat sich Werbung zum Tracking-Werkzeug entwickelt: Unternehmen sammeln Daten über Klicks, Verhalten und Interessen. Historisch begann das Web werbefrei, erst Ende der 1990er kamen die ersten Banner, später komplexe Werbenetzwerke. Mit steigender Monetarisierung stieg auch der Missbrauch: Malware über Anzeigen, unerlaubtes Datensammeln und überladene Seiten.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Und das ist heute noch viel professioneller geworden.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="los-bandidos.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Die vier Schurken"
width="1536"
height="1024"
src="/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/los-bandidos_hu_c62c6c133854ff66.webp"
srcset="/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/los-bandidos_hu_c62c6c133854ff66.webp 800w, /post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/los-bandidos_hu_ece06276005b851.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/los-bandidos.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ich will es einmal überspitzt formulieren:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google&lt;/strong&gt; weiß, was du vor 3 Wochen gefrühstückt hast und wo du deinen nächsten Urlaub planst.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon&lt;/strong&gt; kennt dein Einkaufsverhalten auswendig und schlägt dir genau in diesem Moment vor, was du als nächstes kaufen sollst.&lt;/li&gt;
&lt;li&gt;Deine Seele (und privaten Fotos) hast du über &lt;em&gt;Facebook&lt;/em&gt;, &lt;em&gt;Instagram&lt;/em&gt; oder &lt;em&gt;WhatsApp&lt;/em&gt; bereits an &lt;strong&gt;Meta&lt;/strong&gt; verkauft.&lt;/li&gt;
&lt;li&gt;Und deine eigene Meinung? Nun, die bildet &lt;strong&gt;TikTok&lt;/strong&gt; natürlich gezielt für dich, indem es dir maßgeschneiderte und wegweisende Inhalte präsentiert.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Du &lt;strong&gt;nutzt diese Dienste nicht&lt;/strong&gt; und bist safe? Haha. &lt;strong&gt;Trotzdem&lt;/strong&gt; erhalten sie laufend deine Daten – und zwar jedes Mal dann, wenn du völlig genervt auf &lt;em&gt;Alles akzeptieren&lt;/em&gt; bei einem der abertausenden Cookie-Banner klickst. Oder wenn ein Dienstanbieter die DSGVO wieder einmal nicht einhält und auch ohne dein Einverständnis durch die Gegend telefoniert.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Ich habe diese Unternehmen beispielhaft benannt, einfach weil sie jeder kennt oder nutzt. Es gibt eine große Reihe weiterer teils aggressiver Datensammler, die ebenfalls in sehr vielen Webdiensten eingebunden sind.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Glaubst du mir nicht, &lt;em&gt;alles Science Fiction&lt;/em&gt; oder ist dir egal, hast ja schließlich nichts zu verbergen? Das ist gar nicht schlimm, denn so ticken die allermeisten Menschen. Nicht umsonst sind die Bosse dieser Unternehmen schließlich superreich – und alle anderen Menschen nicht.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Privatsphäre
&lt;div id="privatsphäre" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#privatsph%c3%a4re" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Letzten Endes musst du für dich selbst entscheiden, was für dich wichtig ist. An dieser Stelle möchte ich einfach nur dein Bewusstsein dafür schärfen, &lt;strong&gt;dass solche Dinge tatsächlich stattfinden&lt;/strong&gt;. Mir persönlich geht es hierbei um mein Mitspracherecht. Ich möchte selbst entscheiden können, welche Dienstanbieter über mich Bescheid wissen. Ich möchte gefragt werden, ob das in Ordnung für mich ist. Die Industrie möchte aber genau dieses nicht tun müssen und mich bevormunden.&lt;/p&gt;
&lt;p&gt;Und &lt;strong&gt;genau darum&lt;/strong&gt; setze ich &lt;strong&gt;DNS-Blocking&lt;/strong&gt; ein: um mir einen kleinen Teil meines Mitspracherechts zurückzuholen.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Lösungen
&lt;div id="lösungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#l%c3%b6sungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Ich bevorzuge eine technisierte Welt, weil Technik uns im Alltag unterstützen kann. Doch es geht den Akteuren &lt;strong&gt;nicht in erster Linie&lt;/strong&gt; darum, eine &lt;strong&gt;bessere Welt&lt;/strong&gt; zu erschaffen, einfach weil das ja so toll wäre. Es geht darum, &lt;strong&gt;maximal zu kassieren&lt;/strong&gt;. Das ist die &lt;strong&gt;Quintessenz&lt;/strong&gt; der ganzen Nummer, denn es handelt sich um Wirtschaftsunternehmen. Der &lt;strong&gt;Preis&lt;/strong&gt; dafür sind einfach &lt;strong&gt;unsere Daten&lt;/strong&gt;. Du hast doch nicht ernsthaft geglaubt, dass &lt;em&gt;Facebook&lt;/em&gt;, &lt;em&gt;WhatsApp&lt;/em&gt; und Co. wirklich gänzlich kostenlos zur Verfügung stehen?&lt;/p&gt;
&lt;p&gt;Und dann gäbe es schließlich noch die wirklich &lt;em&gt;bösen Jungs&lt;/em&gt;, die deine Daten mit &lt;strong&gt;kriminellen Methoden&lt;/strong&gt; sammeln – nur um am Ende ebenso maximal zu kassieren.&lt;/p&gt;
&lt;p&gt;Also, was kann man &lt;strong&gt;dagegen tun&lt;/strong&gt;? Die Wahrheit ist: leider gar nichts. Denn ohne Internet geht heutzutage nur wenig, in Zukunft vermutlich gar nichts mehr. Aber man kann die Datensammelwut oder kriminellen Energien zumindest im heimischen Netzwerk &lt;strong&gt;etwas einschränken&lt;/strong&gt; &amp;#x1f604;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Möglichkeiten
&lt;div id="möglichkeiten" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#m%c3%b6glichkeiten" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Genug Theorie. Du bist also am Einsatz von &lt;strong&gt;DNS-Blocking&lt;/strong&gt; interessiert. Woher ich das weiß? Du liest schließlich gerade meinen Artikel darüber. Aber nicht ich wusste, dass du dich dafür interessieren könntest, sondern &lt;em&gt;Google&lt;/em&gt; &amp;#x1f60e;.&lt;/p&gt;
&lt;p&gt;Ein &lt;strong&gt;DNS-Blocker&lt;/strong&gt; ist ein kleines Stückchen Software, welches du in deinem Heimnetzwerk bereitstellen kannst. Solche Tools erfreuen sich immer größerer Beliebtheit im privaten Umfeld und sind zumindest für mich gar nicht mehr wegzudenken.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Die Bekanntesten sind wohl:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="width-patch"&gt;&lt;/div&gt;
&lt;div id="gallery-b519dff33c6f5a79dde514c8be2ba000" class="gallery"&gt;
&lt;a href="https://adguard.com/de/adguard-home/overview.html" target="_blank" class="grid-w33"&gt;&lt;img src="/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/dns-block-gallery/adguard-logo.webp" alt="Bild: AdGuard Home" class="grid-w100" /&gt;&lt;/a&gt;
&lt;a href="https://pi-hole.net" target="_blank" class="grid-w33"&gt;&lt;img src="/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/dns-block-gallery/pihole-logo.webp" alt="Bild: Pi-hole" class="grid-w100" /&gt;&lt;/a&gt;
&lt;a href="https://technitium.com/dns/" target="_blank" class="grid-w33"&gt;&lt;img src="/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/dns-block-gallery/technitium-logo.webp" alt="Bild: Technitium DNS" class="grid-w100" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Mit einem Klick auf das Logo gelangst du direkt zur jeweiligen Projekt-Webseite und kannst dich darüber informieren. Ich selbst habe mich für &lt;strong&gt;&lt;a href="https://pi-hole.net" target="_blank" rel="noopener noreferrer"&gt;Pi-hole &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; entschieden, weil es im Gegensatz zu den anderen Lösungen sehr &lt;strong&gt;vielfältige Möglichkeiten&lt;/strong&gt; bietet, je nach &lt;strong&gt;Client&lt;/strong&gt; oder IP-Adressbereich &lt;strong&gt;unterschiedliche Blocklisten&lt;/strong&gt; einzusetzen.&lt;/p&gt;
&lt;p&gt;Alles, was du benötigst, ist ein (Mini-)Computer, auf dem der Dienst dann laufend ausgeführt und in deinem Heimnetzwerk erreichbar ist. Falls du bisher gar nicht mit solcher Technik ausgestattet sein solltest, wäre ein &lt;strong&gt;&lt;a href="https://amzlink.to/az00RtBaTKz5C" target="_blank" rel="noopener noreferrer"&gt;Raspberry Pi Mini-Computer &lt;i class="ti ti-shopping-cart-share" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; ein guter Einstieg.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="failure"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"&gt;&lt;path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Failure
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Ja, ich bin mir der Ironie absolut bewusst, gerade einen Amazon-Link bereitzustellen. Du kannst jedoch selbst entscheiden, ihn anzuklicken oder es einfach zu lassen &amp;#x1f604;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Es gibt im Internet unzählige Leitfäden, einen &lt;strong&gt;Raspberry Pi mit Pi-hole&lt;/strong&gt; einzurichten. Ich finde &lt;a href="https://www.raspberrypi.com/tutorials/running-pi-hole-on-a-raspberry-pi/" target="_blank" rel="noopener noreferrer"&gt;diesen hier &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; sehr strukturiert und verständlich erklärt.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Los geht&amp;rsquo;s
&lt;div id="los-gehts" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#los-gehts" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Nachdem du einen &lt;strong&gt;DNS-Blocker&lt;/strong&gt; deiner Wahl installiert und in Betrieb genommen hast, richtest du ihn schlussendlich als DNS-Server in deinem Heimnetz ein. Wie genau das funktioniert, hängt stark von deinem Router ab.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hier die gängigsten Geräte:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://fritz.com/apps/knowledge-base/FRITZ-Box-4050/165_Andere-DNS-Server-in-FRITZ-Box-einrichten/" target="_blank" rel="noopener noreferrer"&gt;FRITZ!Box – Lokalen DNS-Server einrichten &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.chip.de/ratgeber/wifi-dsl-internet/speedport-dns-server-aendern-so-geht-s_87d1beee-e95b-4fca-a00d-d9aa54f34f55.html" target="_blank" rel="noopener noreferrer"&gt;Speedport (Telekom) – DNS-Server ändern &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Vodafone Station&lt;/em&gt; – mit Bordmitteln scheinbar nicht möglich, hier muss dein DNS-Blocker gleich als kompletter DHCP-Server eingetragen werden. Vodafone halt.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dein &lt;strong&gt;DNS-Blocker&lt;/strong&gt; wird von deinem Router nun als &lt;strong&gt;DNS-Server&lt;/strong&gt; an die Endgeräte &lt;strong&gt;im Heimnetzwerk&lt;/strong&gt; verteilt. Um das sofort zu erzwingen, kannst du die Endgeräte einfach erneut mit dem Netzwerk verbinden lassen. Kurz darauf beginnt dein DNS-Blocker mit der Auflösung von DNS-Anfragen und stellt dir sogar &lt;strong&gt;Statistiken&lt;/strong&gt; darüber bereit:&lt;/p&gt;
&lt;p&gt;&lt;a href="pihole-summary.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Pi-hole Zusammenfassung"
width="1008"
height="132"
src="/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/pihole-summary_hu_7f97f49d85ae5eb.webp"
srcset="/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/pihole-summary_hu_7f97f49d85ae5eb.webp 800w, /post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/pihole-summary.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2025-09-23-der-wahnsinn-warum-ich-dns-blocking-verwende/pihole-summary.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An meinen Statistiken kannst du erkennen, dass knapp &lt;strong&gt;20% aller DNS-Anfragen&lt;/strong&gt; bei mir ins Leere laufen und damit geblockt werden. Die Geräte mit den meisten Blockierungen sind neben den Smartphones übrigens &lt;strong&gt;Smart TV&lt;/strong&gt;, &lt;strong&gt;PlayStation 5&lt;/strong&gt; und &lt;strong&gt;Voice Assistants&lt;/strong&gt;. Trotz dieser gewaltigen Summen an Blockierungen funktionieren sie übrigens weiterhin frei von Fehlern und Einschränkungen – also war es unnützer Ballast.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Blocklisten
&lt;div id="blocklisten" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#blocklisten" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Dieser ganze Aufwand wäre nichts wert, wenn du keine Domains blockierst. Doch woher soll man die Information nehmen, &lt;strong&gt;welche Domains&lt;/strong&gt; überhaupt blockiert werden sollten? Natürlich könntest du jede scheinbar unliebsame DNS-Anfrage nun selbst per Hand blockieren. Doch im Anschluss daran solltest du natürlich auch &lt;strong&gt;testen&lt;/strong&gt;, ob deine Entscheidung dafür sorgt, dass z.B. deine &lt;strong&gt;Lieblings-Webseite&lt;/strong&gt; jetzt &lt;strong&gt;nicht mehr funktioniert&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Das würde viel zu aufwändig werden und schnell hättest du keine Lust mehr darauf. Ich übrigens auch nicht. Das Internet lebt von der &lt;strong&gt;Crowd&lt;/strong&gt; und ihrem &lt;strong&gt;Einfallsreichtum&lt;/strong&gt;, und so ist bspw. mit &lt;a href="https://firebog.net" target="_blank" rel="noopener noreferrer"&gt;Firebog &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; eine gute &lt;strong&gt;Blocklisten-Sammlung&lt;/strong&gt; entstanden. Diese stellte auch meinen Start in das &lt;strong&gt;DNS-Blocking&lt;/strong&gt; dar, ist aber mittlerweile aus der Zeit gefallen und wird nicht mehr regelmäßig aktualisiert. Einige der Blocklisten sind mir außerdem &lt;strong&gt;zu restriktiv&lt;/strong&gt; gewesen, sodass ich mich immer wieder selbst dabei ertappt habe, blockierte Domains manuell freizugeben.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Aus diesem Grund solltest du dir dieses Projekt ansehen:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Der Kurator dieser Blocklisten und des gesamten Projekts, &lt;strong&gt;hagezi aka Gerd&lt;/strong&gt;, veröffentlicht jeden Tag ein Update mit dem neusten Fundus an &lt;em&gt;Werbern&lt;/em&gt;, &lt;em&gt;Trackern&lt;/em&gt;, &lt;em&gt;Scammern&lt;/em&gt;, &lt;em&gt;Fake-Shops&lt;/em&gt; und &lt;em&gt;sonstigem Kram&lt;/em&gt;, dem man im Internet besser nicht vertrauen sollte.&lt;/p&gt;
&lt;p&gt;Großartig bei diesem Projekt ist außerdem, dass du dir entweder eine &lt;strong&gt;kuratierte Gesamt-Blockliste&lt;/strong&gt; (in den Ausprägungen &lt;em&gt;light&lt;/em&gt;, &lt;em&gt;normal&lt;/em&gt;, &lt;em&gt;pro&lt;/em&gt;, &lt;em&gt;pro++&lt;/em&gt; und &lt;em&gt;ultimate&lt;/em&gt;) in deinen &lt;strong&gt;DNS-Blocker&lt;/strong&gt; laden kannst. Oder aber du abonnierst die &lt;strong&gt;Themen-Blocklisten&lt;/strong&gt; (bspw. &lt;em&gt;NSFW&lt;/em&gt;, &lt;em&gt;Gambling&lt;/em&gt;, &lt;em&gt;Threat Intelligence Feeds&lt;/em&gt;, etc.), einzeln, wie du sie brauchst. Diesen Weg habe ich gewählt, da ich mein &lt;strong&gt;Heimnetz segmentiert&lt;/strong&gt; habe und unterschiedliche &lt;strong&gt;Blocklisten-Kombinationen&lt;/strong&gt; für die verschiedenen Netzsegmente verwende.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;&lt;strong&gt;Beispiel:&lt;/strong&gt; unser Home-WLAN ist weniger restriktiv als unser Gäste-Netz. Beim Surfen möchte ich nicht durch zu intensives Blocking gestört werden und beschränke mich hierbei gezielt auf &lt;em&gt;Werbung&lt;/em&gt;, &lt;em&gt;Tracking&lt;/em&gt; und &lt;em&gt;Security&lt;/em&gt;. Unsere Gäste kommen darüber hinaus in den Genuss von &lt;em&gt;Gambling&lt;/em&gt;- und &lt;em&gt;NSFW&lt;/em&gt;-Filtern – das können sie gern zu Hause machen &amp;#x1f601;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Es soll nicht unerwähnt bleiben, dass &lt;strong&gt;hagezi&lt;/strong&gt; nicht nur eine großartige Sammlung bereitstellt. Im täglichen Einsatz wirst du feststellen, dass der von deinen &lt;strong&gt;Lieblingsdiensten&lt;/strong&gt; benötigte &lt;strong&gt;Traffic durchgelassen&lt;/strong&gt; wird und sie in den meisten Fällen weiterhin korrekt funktionieren. &lt;strong&gt;Das&lt;/strong&gt; ist für mich der &lt;strong&gt;ausschlaggebende Punkt&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Das gesamte Thema rund um &lt;strong&gt;DNS und Blocking&lt;/strong&gt; ist sehr interessant und kann eine Menge Spaß machen. Es fühlt sich gut an, diesem Datensammelwahnsinn zumindest etwas Einhalt zu gebieten. Der Nachteil daran ist, dass du dich nach einer Weile an das saubere Internet gewöhnst. Manchmal bin ich wirklich erschrocken, wenn ich außerhalb des Heimnetzwerks surfe und sehe, wie meine Lieblingswebseiten &lt;strong&gt;in Wirklichkeit&lt;/strong&gt; aussehen.&lt;/p&gt;
&lt;p&gt;Ein weiterer Pluspunkt ist, dass du Schwarz auf Weiß sehen kannst, wohin deine Geräte die ganze Zeit &lt;em&gt;telefonieren&lt;/em&gt;. Auch dann, wenn du sie gerade nicht benutzt. Du wirst dich wundern, was in deinem Zuhause alles abgeht, von dem du bisher nichts gewusst hast.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Viel Spaß&lt;/strong&gt; beim Blockieren &amp;#x1f60e;!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@morganeper?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Morgane Perraud &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/weisse-und-braune-holzwand-mit-weisser-und-schwarzer-holzbeschilderung-0gDfRhgmqDM?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Erfahrungsbericht: 5 Jahre ohne Brille</title><link href="https://tbsch.de/post/2025-08-29-erfahrungsbericht-5-jahre-ohne-brille/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2025-08-29-erfahrungsbericht-5-jahre-ohne-brille/</id><published>2025-08-29T00:00:00Z</published><updated>2025-08-29T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="meinung"/><category term="bericht"/><category term="gesundheit"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2025-08-29-erfahrungsbericht-5-jahre-ohne-brille/featured.webp"/><summary type="html">Meine Augen lasern zu lassen, war eine der besten Entscheidungen meines Lebens.</summary><content type="html">&lt;div class="lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl"&gt;
Eine der besten Entscheidungen meines Lebens war, es ohne Brille führen zu wollen.
&lt;/div&gt;
&lt;p&gt;Blickst du auch manchmal zurück und fragst dich, was du in deinem Leben richtig oder komplett falsch gemacht hast? Seit die Tage immer weniger werden, die mir noch bis zur magischen 4 vorne im Alter verbleiben, denke ich immer öfter darüber nach. Warum ist das so? Ich habe keinen Schimmer, allerdings kann es ja auch gar nicht so falsch sein, sich mit den getroffenen Entscheidungen immer wieder mal auseinanderzusetzen.&lt;/p&gt;
&lt;p&gt;Denn auch in den nächsten 40 Jahren werde ich noch viele Entscheidungen treffen müssen - sei es für mich selbst, für mein Kind oder die ganze Familie. Und jede davon soll ein kleines bisschen besser, weiser, vorausschauender sein als die, die ich zuvor einmal getroffen habe.&lt;/p&gt;
&lt;p&gt;Heute möchte ich über eine meiner Entscheidungen schreiben, die ich absolut richtig getroffen habe: mein &lt;strong&gt;Nein&lt;/strong&gt; zur Brille und das absolute &lt;strong&gt;Ja&lt;/strong&gt; zur Augen-Operation.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Dieser Beitrag ist sehr lang, aus diesem Grund habe ich versucht, ihn in logische Zeitabschnitte aufzuteilen. Weiterhin berichte ich transparent über alle mir entstandenen Kosten in jedem Zeitabschnitt.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Rückblick
&lt;div id="rückblick" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#r%c3%bcckblick" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Genau weiß ich es gar nicht mehr: meine erste Brille muss ich bekommen haben, als ich ungefähr 10 Jahre alt war. Als Kind habe ich dieses Ding einfach nicht gemocht - wie vermutlich alle Kinder. Irgendwann hat man sich aber schließlich doch daran gewöhnt, weil man damit einfach etwas sehen konnte. Und ohne halt nicht. So einfach ist das.&lt;/p&gt;
&lt;p&gt;Viel zu schnell gewöhnt man sich auch an die ganzen kleinen Einschränkungen: Beim Sport rutscht die Brille ständig runter, wenn man schwitzt. Während eines Friseurbesuchs kann man nicht sehen, was gerade auf dem eigenen Kopf passiert. Auf dem Sofa schmerzt es irgendwann, seitlich auf einem Kissen zu liegen, weil die Brille gegen Kopf und Ohr drückt. Und noch viel mehr. Kommt dir bekannt vor &amp;#x1f601;?&lt;/p&gt;
&lt;p&gt;Eines wunderschönen Frühlingstages in 2017 wachte ich auf dem Sofa auf und stellte fest, dass ich abends einfach beim Fernsehen eingeschlafen sein muss. Und da war es passiert: Ich habe auf meiner Brille geschlafen, sie war in der Mitte am Nasensteg glatt durchgebrochen. Seinerzeit wohnte ich auf dem Dorf und ohne Auto gab es keinen Weg in die Stadt, und natürlich musste ich auch noch auf die Arbeit fahren – der Ärger war perfekt, denn ohne Brille konnte ich nichts sehen und, hier sind wir übrigens bei einer meiner dümmsten Entscheidungen: ich hatte keine Ersatzbrille &amp;#x1f604;.&lt;/p&gt;
&lt;p&gt;Eine Taxifahrt später und mit 25 Euro weniger in der Tasche gab ich meine Brille schließlich bei einer dir sicherlich bekannten Optiker-Kette zur Reparatur. Und dank meiner Brillenversicherung, die ich scheinbar beim Brillenkauf versehentlich abgeschlossen haben muss, um beim Kaufpreis zu sparen, erhielt ich zur Überbrückung kostenlose Kontaktlinsen in meiner Sehstärke - für insgesamt 14 Tage.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Entscheidung
&lt;div id="entscheidung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#entscheidung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Diese zwei Wochen haben mein Leben verändert. Das war wie eine &lt;em&gt;Inception&lt;/em&gt;, ich wurde diesen Gedanken einfach nicht mehr los, dass ich keine Brille mehr tragen möchte. Nie wieder! Aber einfach nur auf Linsen umzusteigen, ging mir nicht weit genug. Ich wollte einfach gar keine Sehhilfe mehr haben.&lt;/p&gt;
&lt;p&gt;Natürlich habe ich öfter mal darüber nachgedacht, wie es wäre, sich die Augen operieren zu lassen. Das tut bestimmt jeder Brillenträger gelegentlich. Zumindest bis man dann Google anwirft und sich grob über die Kosten der Operation informiert. Wahnsinn. Von dem Geld könnte ich mir vier MacBooks kaufen, mehrere Male in den Urlaub fliegen oder mir eine Karibik-Kreuzfahrt mit Balkonzimmer buchen.&lt;/p&gt;
&lt;p&gt;Meine damaligen finanziellen Möglichkeiten hätte dieser Eingriff definitiv überschritten, also begann ich Mitte 2018, mir jeden Monat sämtliche Überschüsse meines Gehalts dafür zurückzulegen. Infolgedessen habe ich mir mehr Zeit bei anderen Dingen gelassen, die ich ansonsten frequentierter getan hätte: zum Beispiel meinen Gaming-PC aufrüsten. Man muss ja nicht immer alles sofort haben wollen &amp;#x1f601;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Erstuntersuchung
&lt;div id="erstuntersuchung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#erstuntersuchung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Im Januar 2020 war es dann schließlich so weit: ich reservierte mir für März 2020 einen Termin zur Erstuntersuchung und Beratung im &lt;a href="https://freevis.de" target="_blank" rel="noopener noreferrer"&gt;FreeVis LASIK Zentrum &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; des Uniklinikums Mannheim. Ich habe mich für diese Klinik entschieden, da ich damals in Mannheim wohnte und es sich um eines der führenden Augenlaserzentren Europas handelt - das passte einfach perfekt!&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="warning"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Warning
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Es ist wichtig zu wissen, dass es sich auch bei einer Erstuntersuchung um &lt;strong&gt;keine Leistung der Krankenkasse&lt;/strong&gt; handelt. Es spielt also keine Rolle, ob die Untersuchung einen guten oder schlechten Ausgang hat – die Kosten dafür müssen selbst getragen werden. Es schadet aber nicht, mit deiner Krankenkasse über dein Vorhaben zu sprechen. Manchmal ist unter bestimmten Voraussetzungen vielleicht etwas für dich drin.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Während der Untersuchung wurde die Ist-Situation einmal komplett vom Ärzte-Team erfasst, indem diverse Sehtests mit mir durchgeführt wurden. Die Ergebnisse der Tests bildeten dann die Grundlage für das direkt folgende Beratungsgespräch mit dem behandelnden Arzt, in meinem Fall Prof. Dr. Knorz höchstpersönlich.&lt;/p&gt;
&lt;p&gt;Die Untersuchungsergebnisse belegten, dass ich für eine Augenlaser-Operation in Frage kam. Da ich mich im Vorfeld intensiv mit den Laser-Techniken befasst hatte, wünschte ich mir die Durchführung der &lt;a href="https://freevis.de/relex-smile/index.html" target="_blank" rel="noopener noreferrer"&gt;SMILE LASIK &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;. Bei dieser Methode bleibt der größte Teil der Hornhautschichten des Auges unberührt, wodurch die biomechanische Stabilität der Hornhaut nur minimal beeinflusst wird. Klang für mich sinnvoll und Prof. Dr. Knorz quittierte meinen Wunsch kurzerhand mit der Aussage, dass es ihn aufgrund meiner Vorbereitung für ein Beratungsgespräch ja fast gar nicht mehr benötigen würde, nachdem wir gemeinsam über die Vor- und Nachteile der Operations-Techniken sinnierten &amp;#x1f604;.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Die &lt;strong&gt;Kosten der Erstuntersuchung&lt;/strong&gt; beliefen sich in meinem Fall auf &lt;strong&gt;280 EUR&lt;/strong&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Operation
&lt;div id="operation" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#operation" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Bereits einen Monat später, also im April 2020, wurde mein Operations-Termin eingeplant. Das LASIK Zentrum legte mir außerdem nahe, nicht allein zum Termin zu erscheinen, sondern jemanden mitzubringen. Ich muss ganz ehrlich sagen, dass ich die ganze Zeit über sehr entspannt auf den Termin gewartet hatte. Die zwei Nächte vorher konnte ich vor Aufregung allerdings kaum noch schlafen. Da mischte sich alles hinein: Vorfreude, Angst, Panik - und die Erinnerung an diese eine fiese Augenlaser-Szene in &lt;em&gt;Final Destination 5&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Völlig übermüdet schnappte ich mir am OP-Tag schließlich meinen Kumpel Dmitrij und fuhr mit ihm in die Klinik. Natürlich mit der Straßenbahn. Es soll nicht unerwähnt bleiben, dass es sich um einen gänzlich ambulanten Eingriff handelte. Aufgrund der Corona-Maßnahmen vor Ort waren wir die einzigen Besucher des LASIK Zentrums an diesem Vormittag. Auch wenn Corona keine tolle Sache war, fand ich ziemlich gut, dass es quasi gar keine Wartezeit gab. Es ging also direkt zur Voruntersuchung, wobei nochmals ähnliche Tests wie bei der Erstuntersuchung gemacht wurden. Das dauerte jedoch deutlich länger als beim ersten Mal, da die Messwerte für den Laser benötigt wurden. Nach etwa einer Stunde durfte ich kurz ins Wartezimmer zurückkehren.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Die &lt;strong&gt;Kosten der Voruntersuchung&lt;/strong&gt; beliefen sich in meinem Fall auf &lt;strong&gt;485 EUR&lt;/strong&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Nach einer kurzen Verschnaufpause im Wartezimmer wurde ich dann vom Ärzte-Team in das OP-Vorzimmer geführt, in dem ich wie eine Mumie gänzlich &lt;em&gt;eingepackt&lt;/em&gt; wurde - damit ich möglichst steril war. Kurz darauf durfte ich mich auf eine Liege legen und bekam Augentropfen, die die Augen betäuben sollten. Nachdem diese 10 Minuten eingewirkt hatten, ging es auch direkt in den OP, in dem mich Prof. Dr. Knorz bereits erwartete.&lt;/p&gt;
&lt;p&gt;Ich kann überhaupt nicht in Worte fassen, was mir in diesem Moment alles durch den Kopf ging: alles und nichts. Pure Aufregung. Mir wurde der Ablauf der Operation erklärt: im Endeffekt sollte ich mich nur unter den Laser legen und in das grüne Licht gucken. Mensch, das kann ja nicht so schwer sein &amp;#x1f601;! Mit Klammern wurden dann noch meine Augenlider fixiert, sodass ich nicht mehr blinzeln konnte. Augentropfen schützten vor Brennen in den Augen.&lt;/p&gt;
&lt;p&gt;Und dann ging es auch schon los, Prof. Dr. Knorz gab das Startsignal und das gesamte Team saß um mich herum. Ich erinnere mich noch, dass eine Assistentin ihre Hand auf mein Knie legte - vermutlich als Beruhigungsmaßnahme. Half leider nur bedingt, in so einem Moment hast du einfach nur Schiss. Es müssen 5 oder 10 Sekunden vergangen gewesen sein, als mir mitgeteilt wurde, dass die Operation geglückt sei. Vielleicht war die Zeitspanne auch länger, es kam mir allerdings wie Sekunden vor.&lt;/p&gt;
&lt;p&gt;Durch meine intensive Vorbereitung wusste ich, was nun passieren würde: durch den Laser schwoll die Hornhaut an und ich erblindete für einen kurzen Moment. Prof. Dr. Knorz erklärte mir nun, dass er jetzt die Lentikelentnahme durch den seitlichen Schnitt in meinen Hornhäuten vornahm. Das sah für mich so aus, als würde man ein Milchglas vor meinen Augen seitlich wegziehen. Dann gab es erneut Augentropfen auf die Augen, die Klemmen wurden gelöst und ich durfte schon wieder aufstehen.&lt;/p&gt;
&lt;p&gt;Es fühlte sich nun so an, als hätte ich zwei Tage lang geweint, aber das Wichtigste war: ich konnte klar sehen, wenn auch noch etwas verschwommen – was nach so einem Eingriff vollkommen normal ist. Das war einfach ein irres Gefühl! In Summe war das Ärzte-Team während des Eingriffs sehr zuvorkommend und routiniert, ich habe mich stets gut abgeholt und aufgehoben gefühlt. Das ist heutzutage in einer Klinik ja leider keine Selbstverständlichkeit mehr.&lt;/p&gt;
&lt;p&gt;Übrigens war der gesamte Eingriff frei von Schmerzen, ich habe nichts gespürt. Auch nach der Operation gab es keinen einzigen Moment, in dem ich Schmerzen, Druck oder Brennen spürte. Bis heute nicht.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Die &lt;strong&gt;Kosten der Operation&lt;/strong&gt; beliefen sich in meinem Fall auf &lt;strong&gt;3.400 EUR&lt;/strong&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Nach der OP
&lt;div id="nach-der-op" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#nach-der-op" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Nachdem ich vom gesamten Team verabschiedet worden war und den OP verlassen hatte, ging es direkt zurück ins Wartezimmer zu meiner Begleitung. Eine Assistentin gab mir dann noch ein Care-Paket an die Hand, bestehend aus einer Sonnenbrille für den Heimweg und sehr vielen verschiedenen Augentropfen. Außerdem gab sie mir noch ein paar Instruktionen mit auf den Weg, wie ich mich zu verhalten habe: nicht ins helle Licht schauen, nur mit gewaschenen Händen ins Gesicht, nicht die Augen reiben.&lt;/p&gt;
&lt;p&gt;Bei den Augentropfen handelte es sich um drei unterschiedliche Medikamente, die für die nächsten Wochen teilweise 3x täglich aufgetragen werden sollten. Das gehörte zu solch einem Eingriff einfach dazu und förderte den Heilungsprozess.&lt;/p&gt;
&lt;p&gt;Durch die Sonnenbrille hindurch konnte ich auf dem Heimweg bereits scharf sehen - dieses Gefühl war einfach unglaublich. Hier wurde mir das erste Mal so richtig bewusst, was keine 60 Minuten vorher mit mir passiert war. Ein Laser hat tatsächlich Haut aus meinen Augen herausgeschnitten. Kaum vorstellbar eigentlich. Ab diesem Moment überwogen einfach nur noch die Glücksgefühle.&lt;/p&gt;
&lt;p&gt;Die ersten Tage konnte ich nicht am Rechner arbeiten, das Licht des Bildschirms war schlichtweg zu grell und es war mir nur möglich, die Inhalte verschwommen zu sehen. Fernsehen war auch nicht drin. Meine natürliche und verdunkelte Umgebung nahm ich allerdings gestochen scharf wahr &amp;#x1f604;. Draußen schien die Sonne, doch musste ich Licht vorerst nach Möglichkeit etwas meiden. Also habe ich die nächsten 3 Tage schlichtweg mit Telefonieren verbracht, ganz oldschool.&lt;/p&gt;
&lt;p&gt;Von Nebenwirkungen bin ich anfangs auch nicht ganz verschont geblieben, gerade in den ersten Tagen nach dem Eingriff sah ich häufig Lichtblitze in der Dunkelheit. Das ist ganz normal, und hörte nach ein paar Wochen schließlich auf. Ein weiterer Nebeneffekt kann übrigens sein, dass man in der Dunkelheit etwas schlechter sieht als vor so einer OP. Dies ist bei mir bis heute noch spürbar, war direkt nach dem Eingriff aber verglichen mit heute deutlich stärker.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Nachuntersuchung
&lt;div id="nachuntersuchung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#nachuntersuchung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Sechs Wochen nach der Operation stand als letzte Maßnahme im Juni 2020 dann noch die Nachuntersuchung an. Hierbei wurde ich erneut einem intensiven Sehtest unterzogen, wie bei der Voruntersuchung und kurz vor dem Eingriff. Im Anschluss gab es dann noch einen weiteren Test, wie man ihn vom Augenarzt kennt, wenn man eine Brille braucht oder den Führerschein beantragen möchte. Das Ergebnis dieses Tests war eine sagenhafte &lt;strong&gt;Fehlsichtigkeit von 0&lt;/strong&gt; (null!) Dioptrien.&lt;/p&gt;
&lt;p&gt;Damit war es offiziell: meine Kurzsichtigkeit wurde &lt;strong&gt;geheilt&lt;/strong&gt;! Kurz darauf erhielt ich noch das augenärztliche Gutachten, mit dem ich meine Sehschwäche aus dem Führerschein austragen lassen durfte und wurde aus der Behandlung entlassen.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Die &lt;strong&gt;Kosten der Nachuntersuchung&lt;/strong&gt; beliefen sich in meinem Fall auf &lt;strong&gt;426 EUR&lt;/strong&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Vom ersten Buchen eines Beratungsgesprächs bis zum Abschluss der Behandlung waren gerade einmal 6 Monate vergangen, obwohl gleichzeitig die Corona-Maßnahmen langsam losgingen. Insgesamt habe ich knapp &lt;strong&gt;4.600 EUR&lt;/strong&gt; für die Heilung meiner Sehschwäche bezahlt.&lt;/p&gt;
&lt;p&gt;Während ich diesen Beitrag schreibe, sind mit dem heutigen Tag etwas mehr als &lt;strong&gt;5 Jahre&lt;/strong&gt; seit dem Eingriff vergangen. Nach dieser langen Zeit kann und möchte ich jedem unzufriedenen Brillenträger nahelegen, sich ernsthaft mit der Korrektur der Sehschwäche auseinanderzusetzen. Mein Leben ist auf so vielfältige Weise so viel besser geworden, seit ich einfach gut sehen kann.&lt;/p&gt;
&lt;p&gt;Ich habe zum Beispiel Spaß an Sport gefunden, obwohl ich mein ganzes Leben lang ein absoluter Sportmuffel war – ich kann schwitzen, ohne dass mir die Brille von der Nase rutscht. Ich habe sogar Gefallen an Sommer und heißen Tagen gefunden. Beim Tauchen erkenne ich unter Wasser etwas. Es sind diese unzähligen kleinen Details, die das Leben so viel toller machen - darüber zu schreiben, würde einen halben Roman füllen.&lt;/p&gt;
&lt;p&gt;Überlegst du dir auch, ob du diesen Schritt gehen möchtest? Meine Empfehlung: hör auf zu überlegen, fang an zu sparen und gehe diesen Weg. Für jeden Cent der OP-Kosten erhältst du im Austausch maximales Wohlfühlgefühl - und das ist schließlich unbezahlbar.&lt;/p&gt;
&lt;p&gt;Du wirst es &lt;strong&gt;nicht bereuen&lt;/strong&gt;!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@brandsandpeople?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Brands&amp;amp;People &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/person-mit-angezundeter-zigarette-im-mund-sWQrD5s0fWc?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Zendure SolarFlow MQTT Passwort knacken</title><link href="https://tbsch.de/post/2025-06-30-zendure-solarflow-mqtt-passwort-knacken/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2025-06-30-zendure-solarflow-mqtt-passwort-knacken/</id><published>2025-06-30T00:00:00Z</published><updated>2025-06-30T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="smart-home"/><category term="energie"/><category term="guide"/><category term="home-assistant"/><category term="solar"/><category term="zendure"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2025-06-30-zendure-solarflow-mqtt-passwort-knacken/featured.webp"/><summary type="html">Zendure SolarFlow lokal über MQTT ohne anonymen Benutzer und mit mehr Sicherheit steuern.</summary><content type="html">&lt;p&gt;Wenn du deine &lt;strong&gt;&lt;a href="https://www.zendure.de" target="_blank" rel="noopener noreferrer"&gt;Zendure SolarFlow Speicherlösung &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; ebenfalls von der Cloud befreit hast, wirst du wahrscheinlich einen MQTT-Broker mit anonymen Logins eingerichtet haben, um an die Sensor-Messwerte zu gelangen.&lt;/p&gt;
&lt;p&gt;In diesem Artikel möchte ich dir zeigen, wie du an das hardcoded Passwort deines SolarFlow-Geräts gelangst. Getestet habe ich das Verfahren mit einem &lt;strong&gt;Hub 2000&lt;/strong&gt;, mit ein bisschen Glück funktioniert es auch bei den anderen Geräten.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Vorgehensweise
&lt;div id="vorgehensweise" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#vorgehensweise" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;h3 class="relative group"&gt;1. Device ID
&lt;div id="1-device-id" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#1-device-id" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Wenn du deinen SolarFlow aus der Cloud befreit hast, verfügst du bereits über seine &lt;em&gt;Device ID&lt;/em&gt;. Falls nicht, schau dir am besten einmal den &lt;a href="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/"&gt;Artikel darüber&lt;/a&gt; von mir an.&lt;/p&gt;
&lt;h3 class="relative group"&gt;2. Passwort ermitteln
&lt;div id="2-passwort-ermitteln" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#2-passwort-ermitteln" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Auf GitHub habe ich ein paar kleine Programme veröffentlicht, mit denen das Passwort ermittelt werden kann. Das Projekt steht dort als &lt;strong&gt;Micro-Webseite&lt;/strong&gt;, &lt;strong&gt;Node.js&lt;/strong&gt;- und &lt;strong&gt;Python&lt;/strong&gt;-Script zur Verfügung.&lt;/p&gt;
&lt;p&gt;Alternativ dazu kannst du das Passwort auch direkt hier ermitteln. Meine Webseite berechnet es für dich direkt in deinem Browser, deine &lt;em&gt;Device ID&lt;/em&gt; wird also nicht an mich übertragen.&lt;/p&gt;
&lt;p&gt;&lt;label for="zen-device-id"&gt;&lt;strong&gt;Device ID:&lt;/strong&gt;&lt;/label&gt;&lt;br&gt;
&lt;input type="text" id="zen-device-id" placeholder="Device ID eingeben" maxlength="20"&gt;&lt;br&gt;&lt;/p&gt;
&lt;div id="zen-output"&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;3. MQTT User konfigurieren
&lt;div id="3-mqtt-user-konfigurieren" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#3-mqtt-user-konfigurieren" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Als &lt;em&gt;Home Assistant&lt;/em&gt; User mit dem &lt;strong&gt;Mosquitto Broker Add-on&lt;/strong&gt; hast du es am einfachsten, denn du musst nur einen kleinen Eintrag in der Konfiguration erzeugen und das Add-on anschließend neu starten.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Zur Veranschaulichung verwende ich &lt;code&gt;ABCdef123&lt;/code&gt; als &lt;em&gt;Device ID&lt;/em&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;username&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ABCdef123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;password&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;A599C0002BC5E5F5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Falls du &lt;strong&gt;nicht&lt;/strong&gt; mit &lt;em&gt;Home Assistant&lt;/em&gt; oder dem Add-on ausgestattet bist und stattdessen einen eigenen &lt;em&gt;mosquitto&lt;/em&gt; Broker betreibst, erzeugst du neue User in der Regel so:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mosquitto_passwd -b /etc/mosquitto/passwd ABCdef123 A599C0002BC5E5F5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Das gilt jedoch nicht für gänzlich andere Broker, wie z.B. &lt;em&gt;EMQX&lt;/em&gt; oder &lt;em&gt;HiveMQ&lt;/em&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Auch wenn das gesamte Prozedere die Sicherheit deines Smart Homes nur minimal tangiert (wenn überhaupt), fühlt man sich doch um einiges wohler, wenn man keinen MQTT-Broker mit anonymen Logins betreiben muss &amp;#x1f601;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@leo_visions_?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Leo_Visions &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/ein-schloss-an-einer-tur-jRo9ensL500?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;script src="/lib/spark-md5/spark-md5.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
(() =&gt; {
const input = document.getElementById('zen-device-id');
const output = document.getElementById('zen-output');
input.addEventListener('input', () =&gt; {
const deviceId = input.value.trim().substring(0, 20);
if (!deviceId) {
output.textContent = '';
return;
}
const hash = SparkMD5.hash(deviceId).toUpperCase();
const password = hash.substring(8, 24);
output.innerHTML = `
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;MQTT User&lt;/td&gt;&lt;td&gt;&lt;code&gt;${deviceId}&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;MQTT Password&lt;/td&gt;&lt;td&gt;&lt;code&gt;${password}&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
`;
});
})();
&lt;/script&gt;</content></entry><entry><title>Zendure SolarFlow lokal über MQTT steuern</title><link href="https://tbsch.de/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/</id><published>2025-06-15T00:00:00Z</published><updated>2025-11-30T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="smart-home"/><category term="energie"/><category term="guide"/><category term="home-assistant"/><category term="solar"/><category term="zendure"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/featured.webp"/><summary type="html">Wie aus Zendure SolarFlow mit lokalem Zugriff noch mehr raus geholt werden kann, und wie man das macht.</summary><content type="html">&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="danger"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"&gt;
&lt;path fill="currentColor" d="M159.3 5.4c7.8-7.3 19.9-7.2 27.7 .1c27.6 25.9 53.5 53.8 77.7 84c11-14.4 23.5-30.1 37-42.9c7.9-7.4 20.1-7.4 28 .1c34.6 33 63.9 76.6 84.5 118c20.3 40.8 33.8 82.5 33.8 111.9C448 404.2 348.2 512 224 512C98.4 512 0 404.1 0 276.5c0-38.4 17.8-85.3 45.4-131.7C73.3 97.7 112.7 48.6 159.3 5.4zM225.7 416c25.3 0 47.7-7 68.8-21c42.1-29.4 53.4-88.2 28.1-134.4c-2.8-5.6-5.6-11.2-9.8-16.8l-50.6 58.8s-81.4-103.6-87.1-110.6C133.1 243.8 112 273.2 112 306.8C112 375.4 162.6 416 225.7 416z"/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Danger
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;&lt;strong&gt;Update 29.06.2025:&lt;/strong&gt; in diesem Artikel beschreibe ich die Vorgehensweise, Zendure SolarFlow lokal über MQTT zu steuern. Hierbei beziehe ich mich auf einen MQTT-Broker mit anonymen Logins, da das verwendete MQTT Passwort von SolarFlow unbekannt ist. Zwischenzeitlich habe ich &lt;strong&gt;einen Weg gefunden&lt;/strong&gt;, das Passwort selbst zu errechnen und SolarFlow direkt mit meinem &lt;em&gt;Home Assistant&lt;/em&gt; Broker und mit Authentifizierung zu verbinden.&lt;/p&gt;
&lt;p&gt;Mehr dazu findest du &lt;a href="/post/2025-06-30-zendure-solarflow-mqtt-passwort-knacken/"&gt;hier&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Seit ich ein kleines Balkonkraftwerk (&lt;a href="/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/"&gt;ich berichtete&lt;/a&gt;) betreibe, war für mich schnell klar: nicht nur den erzeugten Strom verbrauchen, sondern auch speichern. Denn sonst läuft das meiste der gewonnenen Power direkt &lt;strong&gt;ins Netz zurück&lt;/strong&gt; - verschenkte Energie, keinen Cent wert, nutzlos.&lt;/p&gt;
&lt;p&gt;Also musste ein Batteriespeicher her, der sich nahtlos in mein Smart Home-Ökosystem mit &lt;em&gt;&lt;a href="https://www.home-assistant.io" target="_blank" rel="noopener noreferrer"&gt;Home Assistant &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/em&gt; integrieren lässt. Voraussetzung dafür war, dass die Messdaten jederzeit lokal zur Verfügung stehen und stets den aktuellen Status aufweisen. Gibt es in Zeiten von IoT und Smart Home ja ganz bestimmt endlos am Markt &amp;#x1f609; - &lt;em&gt;/sarcasm&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Ich nehme dich nun also mit auf die Reise, von der Entscheidung für eine Speicherlösung bis hin zur Integration in &lt;em&gt;Home Assistant&lt;/em&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Die Suche nach einer Speicherlösung
&lt;div id="die-suche-nach-einer-speicherlösung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#die-suche-nach-einer-speicherl%c3%b6sung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;So begann &lt;strong&gt;Anfang 2024&lt;/strong&gt; mein absoluter Albtraum: Recherche hier, Ratlosigkeit da, Fassungslosigkeit dort. Zum Glück mit einem positiven Erwachen im &lt;strong&gt;Juni 2025&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Überall Cloudzwang
&lt;div id="überall-cloudzwang" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%c3%bcberall-cloudzwang" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Bin ich eigentlich der einzige Mensch auf der Welt, der überhaupt nicht darauf steht, von allen Herstellern mit ihren Apps überschwemmt zu werden? Natürlich alles absolut sicher in ihren Hochsicherheits-Clouds gespeichert, Privatsphäre wird geschützt, etc.pp. Das ist so sicher, wie dass Facebook ernsthaft daran interessiert ist, deine Privatsphäre zu schützen. Du merkst schon, worauf das hinausläuft &amp;#x1f928;.&lt;/p&gt;
&lt;p&gt;Außerdem möchte ich nicht in eine App gucken müssen, wie viel Solarstrom gerade gewonnen, gespeichert und selbst verbraucht werden kann. Davon habe ich nichts außer der Erkenntnis, die Informationen zwar sehen, aber nicht damit arbeiten zu können. Mein Smart Home muss in die Lage versetzt werden, mit diesen Messwerten intelligente Entscheidungen zu treffen. Und da es keine App bedienen kann, habe ich also nichts davon.&lt;/p&gt;
&lt;p&gt;Last but not least sprechen wir hier von kritischen Messwerten, die ich auf keinen Fall nur über das Internet im Zugriff haben möchte. Denn das würde bedeuten: bei einem Internetausfall ist mein Balkonkraftwerk – direkt vor meiner Nase – nicht mehr steuerbar. Das ist absolut nicht erstrebenswert, will man einfach nicht, Red Flag &amp;#x1f6a9;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Anforderungen
&lt;div id="anforderungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#anforderungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Meine Wünsche an eine Speicherlösung sind doch eigentlich gar nicht so speziell:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2 kWh Kapazität, denn mehr fällt bei meiner Anlage derzeit nicht an Überschuss ab&lt;/li&gt;
&lt;li&gt;Kapazität jedoch skalierbar, denn&amp;hellip;&lt;/li&gt;
&lt;li&gt;Solarmodule bis 2400 Wp aufrüstbar&lt;/li&gt;
&lt;li&gt;Lokale Datenverfügbarkeit über REST, MQTT, etc.&lt;/li&gt;
&lt;li&gt;Integration somit in &lt;em&gt;Home Assistant&lt;/em&gt; möglich&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wenn du im Internet nach Batteriespeichern für Balkonkraftwerke suchst, wirst du sehr schnell von &lt;strong&gt;Anker SOLIX&lt;/strong&gt;, &lt;strong&gt;Growatt NOAH&lt;/strong&gt;, &lt;strong&gt;Marstek B2500&lt;/strong&gt;, &lt;strong&gt;Zendure SolarFlow&lt;/strong&gt; und einigen anderen Produkten lesen. Und alle kommen sie mit Cloudzwang ohne lokale Steuerung daher, oder aber auf irgendeine Weise nervtötend eingeschränkt.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Insgesamt habe ich mich ein Jahr mit der Suche nach einer Lösung beschäftigt und mich sehr lange mit den Ergebnissen auseinandergesetzt. Ich wollte einfach unbedingt direkt zu dem für mich passenden Produkt greifen.&lt;/p&gt;
&lt;p&gt;Die Recherche ist allerdings gar nicht so einfach gewesen, da häufig die Informationen nicht so zur Verfügung standen, wie ich es mir wünschte. Bei so einer Investition möchte man im Vorfeld schließlich genau wissen, worauf man sich einlässt. Deshalb passte ich meine Strategie an. Ich kontaktierte den &lt;em&gt;Balkonkraftwerk&lt;/em&gt; Content Creator &lt;a href="https://www.tiktok.com/@m4riore" target="_blank" rel="noopener noreferrer"&gt;&lt;strong&gt;Mario Makowski&lt;/strong&gt; &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;, der die Lösungen diverser Hersteller bereits selbst in der Hand hatte und ausprobieren konnte.&lt;/p&gt;
&lt;p&gt;Er riet mir, mich mit Zendure SolarFlow zu beschäftigen &amp;#x1f914;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Zendure SolarFlow
&lt;div id="zendure-solarflow" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#zendure-solarflow" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Zendure SolarFlow besteht in der Regel aus einer Hub-Einheit und den daran angeschlossenen Speichereinheiten. Ich habe mich für den &lt;strong&gt;Hub 2000&lt;/strong&gt; entschieden, den ich dann bequem an meinen vorhandenen Wechselrichter anschließen konnte.&lt;/p&gt;
&lt;p&gt;Sehen wir uns nun gemeinsam an, wie ich diese Speicherlösung erfolgreich in mein Smart Home integrieren konnte.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Technische Daten zum Zendure SolarFlow findest du &lt;a href="https://www.zendure.de" target="_blank" rel="noopener noreferrer"&gt;hier &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;. In diesem Beitrag geht es stattdessen um die Integration im lokalen Smart Home. Kontaktiere mich gern, wenn du Fragen hast.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;Vorbereitungen
&lt;div id="vorbereitungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#vorbereitungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Eigentlich hatte ich SolarFlow bereits ausgeschlossen, da die Messwerte über MQTT lediglich aus der Herstellercloud abgerufen werden können. Einige Smart Home Nutzer klagten außerdem über die Tatsache, dass die Datenübertragung häufig mit hohen Latenzen verbunden sei und viele Messwerte erst mit einer Verzögerung mehrerer Minuten zur Verfügung stehen.&lt;/p&gt;
&lt;p&gt;Dann entdeckte ich den &lt;strong&gt;SolarFlow Bluetooth Manager&lt;/strong&gt; von &lt;em&gt;Reinhard Weber&lt;/em&gt; auf GitHub.&lt;/p&gt;
&lt;p&gt;Das Tool verspricht, diverse Modellreihen von Zendure aus der Cloud befreien zu können. Hierbei wird per Bluetooth eine Verbindungskonfiguration an das Gerät übertragen, darunter deine WLAN-Einstellungen und Verbindungsoptionen für einen MQTT-Broker. Dass die Zendure App fürs Smartphone dann nicht mehr korrekt arbeiten kann, ist mir sogar mehr als recht &amp;#x1f604;.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="warning"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Warning
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Die nun gezeigte Lösung ist zwar kinderleicht, dennoch nichts für Anfänger. Du benötigst ein Bluetooth-fähiges Gerät, auf dem Python installiert ist. Du solltest dich mit Python auskennen und wissen, wie eine Entwicklungsumgebung eingerichtet und Abhängigkeiten bereitgestellt werden. Ein paar Grundlagen im Umgang mit einem Terminal schaden ebenfalls nicht.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;&lt;strong&gt;Update 30.11.2025:&lt;/strong&gt; vom Leser und Zendure User &lt;strong&gt;Manfred&lt;/strong&gt; habe ich den Hinweis erhalten, dass &lt;strong&gt;SolarFlow Bluetooth Manager&lt;/strong&gt; mit einem &lt;em&gt;Zendure SolarFlow 2400AC&lt;/em&gt; nicht funktioniert. Er teilte mir mit, dass das auch gar nicht nötig wäre, denn dort ist es problemlos möglich, einen eigenen lokalen MQTT-Broker zu konfigurieren. Voraussetzung ist die Deaktivierung des Home Energy Management Systems (HEMS).&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Nachdem ich meine Solarmodule und den Wechselrichter mit Zendure SolarFlow Hub 2000 verbunden hatte und das System betriebsbereit war, habe ich das Gerät mit der Zendure App verbunden und initial eingerichtet: klasse, alles funktioniert einwandfrei und erste Solar-Leistungsdaten flatterten über mich herein.&lt;/p&gt;
&lt;p&gt;Das angebotene &lt;strong&gt;Firmware-Update&lt;/strong&gt; habe ich vorerst ausgelassen, da ich befürchtete, dass die weiteren Schritte danach nicht mehr funktionieren könnten. Die &lt;strong&gt;Version v3.0.21 der MASTER Firmware&lt;/strong&gt; kannst du jedoch bedenkenlos installieren - die habe ich ebenfalls im Einsatz.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="note"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Note
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Ich lege dir nahe, in der App unbedingt direkt das &lt;strong&gt;Output Limit&lt;/strong&gt; herabzusetzen. Das ist die Leistung, mit der SolarFlow Strom an deinen Wechselrichter abgibt. In meinem Fall waren 800 Watt voreingestellt.&lt;/p&gt;
&lt;p&gt;Allerdings habe ich das nicht bemerkt und bis zum Abschluss der Einbindung von SolarFlow in mein Smart Home die volle Power direkt aus der Batterie raus zum Netzbetreiber gejagt &amp;#x1f604;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Danach schnappte ich mir direkt mein MacBook. Hier hatte ich bereits alles für die Ausführung des &lt;strong&gt;SolarFlow Bluetooth Managers&lt;/strong&gt; vorbereitet.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Sprengen der Ketten
&lt;div id="sprengen-der-ketten" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#sprengen-der-ketten" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Auf der &lt;a href="https://github.com/reinhard-brandstaedter/solarflow-bt-manager" target="_blank" rel="noopener noreferrer"&gt;GitHub Seite &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; vom &lt;strong&gt;SolarFlow Bluetooth Manager&lt;/strong&gt; sind alle Befehle sehr gut beschrieben, sodass du sie einfach nach der Reihe ausführen kannst.&lt;/p&gt;
&lt;h4 class="relative group"&gt;1. Infos parat halten
&lt;div id="1-infos-parat-halten" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#1-infos-parat-halten" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Für den lokalen Betrieb von Zendure SolarFlow benötigst du:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;WLAN-Verbindungsdaten (SSID und Passwort).&lt;/li&gt;
&lt;li&gt;MQTT-Broker-Verbindungsdaten (Host und Port), ohne Authentifizierung.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Das war schon alles. SolarFlow verwendet mutmaßlich ein hardcoded Passwort zur Authentifizierung am MQTT-Broker, welches wir nicht kennen. Daher benötigst du einen MQTT-Broker mit erlaubter anonymer Anmeldung.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="note"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Note
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Anonyme Logins auf meinem Smart-Home-MQTT-Broker begeisterten mich wenig, weshalb ich mir in Docker schlichtweg einen extra dafür vorgesehenen Broker hochgezogen habe. Dass das durchaus Sinn ergeben kann, erkläre ich &lt;a href="#2-mqtt-topics-mappen"&gt;weiter unten&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 class="relative group"&gt;2. Umgebung scannen
&lt;div id="2-umgebung-scannen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#2-umgebung-scannen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Ziel ist es, die &lt;em&gt;Device ID&lt;/em&gt; des Zendure-Geräts herauszufinden. Öffne dein Terminal, definiere deine &lt;code&gt;SF_PRODUCT_ID&lt;/code&gt; und starte das Python Skript.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export SF_PRODUCT_ID&lt;span style="color:#f92672"&gt;=&lt;/span&gt;A8yh63 &lt;span style="color:#75715e"&gt;# Zendure SolarFlow Hub 2000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python3 solarflow-bt-manager.py -i&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Schon nach einem kurzen Augenblick werden dir die Infos präsentiert und du kannst die Ausführung des Programms unterbrechen. Notiere dir die &lt;em&gt;Device ID&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="terminal-sfbtm-i.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: SolarFlow Bluetooth Manager - Suchmodus"
width="1980"
height="1134"
src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/terminal-sfbtm-i_hu_48a03fded22f638b.webp"
srcset="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/terminal-sfbtm-i_hu_48a03fded22f638b.webp 800w, /post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/terminal-sfbtm-i_hu_98a6d4ab019e4fbe.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/terminal-sfbtm-i.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sollte das Skript in einen Timeout laufen und keine Geräte finden, stelle sicher, dass die Zendure App auf deinem Smartphone geschlossen und nicht mehr mit SolarFlow über Bluetooth verbunden ist. Das Skript hat mein SolarFlow erst 3 Minuten nach Beenden der App gefunden. Lass dich nicht aus der Ruhe bringen &amp;#x1f60e;.&lt;/p&gt;
&lt;h4 class="relative group"&gt;3. Lokal verbinden
&lt;div id="3-lokal-verbinden" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#3-lokal-verbinden" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Jetzt wird es auch schon richtig ernst, denn die Verbindung zur Zendure Cloud (und damit zur App) wird getrennt. Das Gerät ist im Anschluss nur noch lokal über MQTT steuerbar. Der &lt;strong&gt;SolarFlow Bluetooth Manager&lt;/strong&gt; bietet noch einen Proxy-Mode an, über den die Messwerte lokal bereitstehen und gleichzeitig eine Cloud-Verbindung erhalten bleibt. Das kam für mich persönlich jedoch nicht in Frage.&lt;/p&gt;
&lt;p&gt;Zuerst werden im Terminal wieder ein paar Umgebungsvariablen definiert. Die &lt;code&gt;SF_PRODUCT_ID&lt;/code&gt; hast du in Schritt 2 bereits definiert, der Vollständigkeit halber liste ich sie aber noch einmal auf:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export SF_PRODUCT_ID&lt;span style="color:#f92672"&gt;=&lt;/span&gt;A8yh63 &lt;span style="color:#75715e"&gt;# Zendure SolarFlow Hub 2000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export SF_DEVICE_ID&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;V77...&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# die Device ID aus Schritt 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export WIFI_PWD&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;1234567890&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# dein WLAN Passwort&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export MQTT_USER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# habe hier nur einen Dummy-Wert gesetzt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export MQTT_PWD&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;mqtt_pwd&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# habe hier nur einen Dummy-Wert gesetzt&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Vergewissere dich, dass alle Werte korrekt sind, und führe danach den &lt;em&gt;Disconnect&lt;/em&gt;-Befehl aus. Hierbei musst du deinen WLAN-Netzwerknamen und die IP-Adresse deines lokalen MQTT-Brokers angeben.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python3 solarflow-bt-manager.py -d -w &lt;span style="color:#e6db74"&gt;&amp;#34;WLAN_SSID&amp;#34;&lt;/span&gt; -b &lt;span style="color:#e6db74"&gt;&amp;#34;MQTT_HOST&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Das war es auch schon. Bei mir hat es direkt funktioniert, Troubleshooting war nicht notwendig.&lt;/p&gt;
&lt;h4 class="relative group"&gt;4. Erfolgsprüfung
&lt;div id="4-erfolgsprüfung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#4-erfolgspr%c3%bcfung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Kurz darauf erreichen deinen MQTT-Broker bereits die ersten Nachrichten von Zendure SolarFlow, denn das Gerät berichtet beinahe sekündlich über seinen aktuellen Zustand und übermittelt Telemetrie-Daten.&lt;/p&gt;
&lt;p&gt;&lt;a href="mqtt-explorer-connected.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: MQTT Explorer - SolarFlow sendet Nachrichten"
width="2272"
height="1664"
src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/mqtt-explorer-connected_hu_8b4a607567efaa58.webp"
srcset="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/mqtt-explorer-connected_hu_8b4a607567efaa58.webp 800w, /post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/mqtt-explorer-connected_hu_d5085d63de687e95.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/mqtt-explorer-connected.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ich verwende für solche Zwecke gern das Tool &lt;a href="https://mqtt-explorer.com" target="_blank" rel="noopener noreferrer"&gt;MQTT Explorer &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; von &lt;em&gt;Thomas Nordquist&lt;/em&gt;. Es ist schlank, übersichtlich und Open Source. Falls du es noch nicht installiert hast: Du wirst es im weiteren Verlauf dieses Beitrags noch benötigen &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Herzlichen Glückwunsch&lt;/strong&gt;, dein Zendure SolarFlow ist nun von der Cloud befreit und kann nur noch lokal gesteuert und ausgelesen werden. Du wirst es nicht bereuen!&lt;/p&gt;
&lt;h3 class="relative group"&gt;Smart-Home-Integration
&lt;div id="smart-home-integration" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#smart-home-integration" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Wäre ja zu schön gewesen, wenn nun schon direkt alle Sensoren in &lt;em&gt;Home Assistant&lt;/em&gt; (oder der Smart Home Lösung deiner Wahl) zur Verfügung stehen würden. Allerdings folgt jetzt der Teil der Arbeit, der mir persönlich immer am meisten Spaß macht.&lt;/p&gt;
&lt;h4 class="relative group"&gt;1. Daten analysieren
&lt;div id="1-daten-analysieren" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#1-daten-analysieren" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Zendure SolarFlow sendet haufenweise Nachrichten an die folgenden Topics. Diese solltest du dir im &lt;strong&gt;MQTT Explorer&lt;/strong&gt; näher ansehen und entscheiden, ob du mit den Informationen im Smart Home arbeiten kannst oder nicht.&lt;/p&gt;
&lt;p&gt;Die aus meiner Sicht wichtigsten wären:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;Beschreibung&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/+/+/event/device&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enthält allgemeine Infos zu Laderichtung und Power.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/+/+/log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enthält sämtliche Gerätedaten als Telemetrie-Array.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/+/+/properties/report&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Wichtigstes Topic!&lt;/strong&gt; Hierüber kommen detaillierte Zustandsänderungen.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;iot/+/+/properties/write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hierüber können Befehle an SolarFlow gesendet werden, z.B. Änderung des &lt;strong&gt;Output Limits&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Sehen wir uns das &lt;em&gt;Report-Topic&lt;/em&gt; einmal näher an. Es enthält sehr viele Zustandsmitteilungen zum SolarFlow Hub selbst (&lt;code&gt;properties&lt;/code&gt;), aber auch zu den angeschlossenen Batterien (&lt;code&gt;packData&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;messageId&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;123&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;product&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;solarFlow&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;deviceId&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;V77xxx&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;timestamp&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;847111&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;solarInputPower&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;37&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;packInputPower&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;59&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;solarPower2&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;11&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;packData&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;socLevel&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;38&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;sn&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;CO4xxxxxxxxxx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Eine Auflistung aller Datenpunkte und ihrer Bedeutung wird von Zendure selbst &lt;a href="https://github.com/Zendure/developer-device-data-report?tab=readme-ov-file#solarflow" target="_blank" rel="noopener noreferrer"&gt;auf GitHub &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; bereitgestellt.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 class="relative group"&gt;2. MQTT Topics mappen
&lt;div id="2-mqtt-topics-mappen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#2-mqtt-topics-mappen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Die Herausforderung beim Bau von Sensoren für &lt;em&gt;Home Assistant&lt;/em&gt; ist, dass lediglich &lt;em&gt;veränderte&lt;/em&gt; Datenpunkte in den Payloads enthalten sind. Unveränderte Datenpunkte werden so lange nicht erneut gesendet, bis sie einen anderen Wert angenommen haben.&lt;/p&gt;
&lt;p&gt;Beim &lt;strong&gt;SolarFlow Bluetooth Manager&lt;/strong&gt; ist zwar auf GitHub ein möglicher Lösungsweg &lt;a href="https://github.com/reinhard-brandstaedter/solarflow-bt-manager?tab=readme-ov-file#prettyfying-zendures-mqtt-topics" target="_blank" rel="noopener noreferrer"&gt;dokumentiert &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;, ich habe es jedoch anders gelöst. Wie &lt;a href="#1-infos-parat-halten"&gt;oben&lt;/a&gt; erwähnt, verwende ich einen separaten MQTT-Broker ohne Authentifizierung, an den Zendure SolarFlow nun alle Daten sendet. In &lt;a href="https://nodered.org" target="_blank" rel="noopener noreferrer"&gt;Node-RED &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; habe ich dann einen Flow aufgebaut, der die Topics umbaut und an meinen &lt;em&gt;Home Assistant MQTT Broker&lt;/em&gt; weiterleitet.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Alle wesentlichen Details zu meiner &lt;em&gt;Home Assistant&lt;/em&gt; Installation und den Produkten, die ich verwende, kannst du auf meiner &lt;a href="/smart-home/#home-assistant"&gt;Smart Home Seite&lt;/a&gt; nachschlagen.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Als kleinen Bonus gibt es noch ein zusätzliches Topic von mir, welches den Verbindungsstatus von SolarFlow darstellen kann, und einen &lt;em&gt;Binary Sensor&lt;/em&gt; in &lt;em&gt;Home Assistant&lt;/em&gt;, der diesen Status direkt visualisiert. Das löse ich mit einem &lt;strong&gt;Trigger-Node&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="node-red-topic-mapping.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Node-RED Topic Mapping"
width="1116"
height="379"
src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/node-red-topic-mapping_hu_5dbc3d6f345ca730.webp"
srcset="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/node-red-topic-mapping_hu_5dbc3d6f345ca730.webp 800w, /post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/node-red-topic-mapping.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/node-red-topic-mapping.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Im Wesentlichen habe ich die Logik vom &lt;a href="https://github.com/reinhard-brandstaedter/solarflow-bt-manager/blob/master/src/solarflow-topic-mapper.py" target="_blank" rel="noopener noreferrer"&gt;SolarFlow Topic Mapper &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;, der beim &lt;strong&gt;SolarFlow Bluetooth Manager&lt;/strong&gt; dabei ist, in Node-RED nachgebaut und das gesamte Ergebnis an meine Bedürfnisse angepasst. Deshalb kann ich den Flow gegenwärtig noch nicht öffentlich teilen, kontaktiere mich aber gern, wenn du Fragen dazu hast.&lt;/p&gt;
&lt;p&gt;Nachdem der Flow deployed wurde und seine Arbeit aufgenommen hat, kommen auch schon direkt die Messwerte auf meinem &lt;em&gt;Home Assistant MQTT Broker&lt;/em&gt; an.&lt;/p&gt;
&lt;p&gt;&lt;a href="mqtt-explorer-mapped-topics.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: MQTT Explorer - gemappte Topics"
width="2272"
height="1664"
src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/mqtt-explorer-mapped-topics_hu_648ffec1a68bf5e4.webp"
srcset="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/mqtt-explorer-mapped-topics_hu_648ffec1a68bf5e4.webp 800w, /post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/mqtt-explorer-mapped-topics_hu_9abd547e3c5d2a97.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/mqtt-explorer-mapped-topics.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sicher kannst du auf einen Blick erkennen, welches Wetter hier gerade ist, während ich diesen Beitrag schreibe &amp;#x1f60e;.&lt;/p&gt;
&lt;h4 class="relative group"&gt;3. Sensoren definieren
&lt;div id="3-sensoren-definieren" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#3-sensoren-definieren" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Im letzten Schritt steht die eigentliche Integration der Messwerte in &lt;em&gt;Home Assistant&lt;/em&gt; an, nachdem sie nun sauber über MQTT transportiert werden. Ich habe ein paar Stunden Arbeit in die eigene Gestaltung der Sensoren gesteckt, da die im Internet zur Verfügung stehenden Konfigurationen mir schlichtweg nicht gefallen haben, unvollständig waren oder sogar Fehler hatten.&lt;/p&gt;
&lt;p&gt;Die beiden folgenden &lt;em&gt;YAML&lt;/em&gt;-Dateien werden von &lt;em&gt;Home Assistant&lt;/em&gt; geladen, da ich folgenden Eintrag in meiner &lt;code&gt;configuration.yaml&lt;/code&gt; angelegt habe:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;mqtt&lt;/span&gt;: !&lt;span style="color:#ae81ff"&gt;include_dir_merge_list includes/mqtt/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/tb1337/1d0b81c543a90da8611553cee560003b#file-homeassistant_mqtt_zendure_hub-yaml" target="_blank" rel="noopener noreferrer"&gt;homeassistant_mqtt_zendure_hub.yaml &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/tb1337/1d0b81c543a90da8611553cee560003b#file-homeassistant_mqtt_zendure_pack-yaml" target="_blank" rel="noopener noreferrer"&gt;homeassistant_mqtt_zendure_pack.yaml &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dir ist sicher aufgefallen, dass die Sensoren das in &lt;a href="#2-mqtt-topics-mappen"&gt;Punkt 2&lt;/a&gt; erwähnte MQTT Topic zum Verbindungsstatus verwenden. Sollte mein Zendure SolarFlow einmal länger als drei Minuten keine Daten senden, stellen sich die Sensoren alle auf den Status &lt;em&gt;nicht verfügbar&lt;/em&gt; um.&lt;/p&gt;
&lt;h4 class="relative group"&gt;4. Ergebnis
&lt;div id="4-ergebnis" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#4-ergebnis" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Nach der ganzen Theorie wird es nun Zeit, das Ergebnis zu sehen - bzw. einen kleinen Ausschnitt davon. Ich möchte dich ja nicht spoilern und dir die Möglichkeit geben, diesen &lt;strong&gt;Moment des Erfolgs&lt;/strong&gt; in deinem eigenen Smart Home genießen zu können &amp;#x1f604;.&lt;/p&gt;
&lt;p&gt;&lt;a href="ha-zendure.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: MQTT Explorer - gemappte Topics"
width="1352"
height="1130"
src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/ha-zendure_hu_a3f0930a831d9741.webp"
srcset="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/ha-zendure_hu_a3f0930a831d9741.webp 800w, /post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/ha-zendure_hu_2bd316572cb199db.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/ha-zendure.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 class="relative group"&gt;Nächste Schritte
&lt;div id="nächste-schritte" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#n%c3%a4chste-schritte" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Nachdem Zendure SolarFlow in dein Smart Home integriert wurde und die Sensorik sowie grundlegende Steuerung jetzt funktioniert, liegt es nun an dir, für &lt;strong&gt;Intelligenz im Lade-/Entlade-Verhalten&lt;/strong&gt; zu sorgen.&lt;/p&gt;
&lt;p&gt;Ich möchte dir an dieser Stelle ein paar Konfigurations-Entitäten für den Anfang mit auf den Weg geben, über die sich bereits viel erreichen lässt:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Einstellung&lt;/th&gt;
&lt;th&gt;Bedeutung/Auswirkung&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Output Limit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Legt fest, wie viel Leistung an deinen Haushalt abgegeben wird. SolarFlow versucht immer, diesen Wert zu erreichen - mit direktem Verbrauch deiner aktuellen Solarpower oder vorhandener Batterieladung, oder einem Mix aus beidem. Wenn mehr Solarstrom produziert wird als abgegeben werden soll, wird in der Folge die Batterie aufgeladen.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SoC Min&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Die Schwelle für die Mindestladung der Batterie, ich verwende hier in der Regel 20%. SolarFlow wird die Batterie mindestens bis zu diesem Wert aufladen und nichts an den Haushalt abgeben, während Solarstrom produziert wird. Beim Entladen wird dieser Wert niemals unterschritten. Du kannst das System &lt;em&gt;zwingen&lt;/em&gt;, die Aufladung der Batterie zu priorisieren, wenn du den Wert bspw. auf 80% einstellst. Da gibt es interessante Möglichkeiten.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SoC Set&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Die Schwelle für die Maximalladung der Batterie, ich verwende hier einen Wert &amp;gt;=80%. SolarFlow wird die Batterie bis zu diesem Wert aufladen und anschließend den &lt;em&gt;Battery Bypass&lt;/em&gt; aktivieren. Ab hier wird sämtliche produzierte Solarpower direkt an den Haushalt abgegeben, ohne die Batterie zu laden.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Battery Bypass&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Kann drei Zustände annehmen. &lt;em&gt;Immer ein&lt;/em&gt; klemmt die Batterie vom Kreislauf immer ab. &lt;em&gt;Immer aus&lt;/em&gt; lädt und entlädt die Batterie in Abhängigkeit der anderen Einstellungen. &lt;em&gt;Automatisch&lt;/em&gt; lässt SolarFlow selbst entscheiden, ob die Batterie am Kreislauf teilnimmt, oder nicht. Ich verwende in der Regel &lt;em&gt;Automatisch&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Mein Ziel ist, immer den &lt;strong&gt;aktuellen Leistungsbedarf&lt;/strong&gt; im Haushalt &lt;strong&gt;mit Sonnenkraft&lt;/strong&gt; zu decken, die &lt;strong&gt;Überkapazitäten zu speichern&lt;/strong&gt; und nach Möglichkeit &lt;strong&gt;niemals&lt;/strong&gt; Strom an das &lt;strong&gt;öffentliche Netz&lt;/strong&gt; abzugeben. Nach Sonnenuntergang wird die Batterie anschließend in der Höhe meiner Grundlast entladen. So verbrauche ich die meiste Solarpower direkt und schaffe mir zusätzlich eine kleine Ersparnis für die Nacht.&lt;/p&gt;
&lt;p&gt;Da ich einen Stromtarif mit fixem Arbeitspreis verwende, spielt es keine Rolle, wann ich Energie verbrauchen oder speichern muss - sie kostet immer dasselbe. Sparen kann ich also nur, wenn ich das Maximum an selbstproduziertem Strom selbst verbrauchen kann. Und genau das ist meine Strategie.&lt;/p&gt;
&lt;p&gt;Hätte ich einen &lt;strong&gt;dynamischen Stromtarif&lt;/strong&gt;, sähe das Ganze wiederum komplett anders aus. Hier kann das Ziel nur sein, Strom immer dann aus dem Netz zu beziehen, wenn er günstig ist, und teure Zeitintervalle mit Eigenproduktion zu decken. Diese Tarife sprechen mich zwar aufgrund ihrer Möglichkeiten an, sind mir gegenwärtig allerdings zu risikobehaftet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Als Nächstes&lt;/strong&gt; werde ich darüber berichten, wie ich die ganzen Messwerte für das &lt;em&gt;Home Assistant&lt;/em&gt; Energie-Dashboard passend gemacht habe.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 class="relative group"&gt;Empfehlung
&lt;div id="empfehlung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#empfehlung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Und noch etwas in eigener Sache:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Seit kurz nach dem Marktstart in Deutschland bin ich überzeugter Kunde bei &lt;strong&gt;&lt;a href="https://share.octopusenergy.de/tulip-eel-28" target="_blank" rel="noopener noreferrer"&gt;Octopus Energy &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt;, mittlerweile in einem noch günstigeren Treuetarif.&lt;/p&gt;
&lt;p&gt;Während der Energiekrise 2022 hatten wir gegenseitig ein einmonatiges Kündigungsrecht, im Gegensatz zu vielen schwarzen Schafen am Markt haben sie weder davon, noch einer Preisanpassung mir gegenüber, Gebrauch gemacht. Im Gegenteil: sie haben den Preis nach dem Wegfall der EEG-Umlage sogar noch gesenkt. So bin ich mit knapp unter 30 Cent Arbeitspreis durch die Krise gekommen, mit mir haben sie definitiv kein Geld verdient.&lt;/p&gt;
&lt;p&gt;Aber sie waren mir treu und im Gegenzug erzähle ich jedem davon &amp;#x1f601;.&lt;/p&gt;
&lt;div class="width-patch"&gt;&lt;/div&gt;
&lt;div id="gallery-6383d5e0b8a1734fde42326eff712f24" class="gallery"&gt;
&lt;a href="https://share.octopusenergy.de/tulip-eel-28" class="grid-w50" target="_blank"&gt;&lt;img src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/octopus-energy-gallery/logo.webp" alt="Octopus Energy" class="grid-w100" /&gt;&lt;/a&gt;
&lt;a href="https://share.octopusenergy.de/tulip-eel-28" class="grid-w25" target="_blank"&gt;&lt;img src="/post/2025-06-15-zendure-solarflow-lokal-%C3%BCber-mqtt-steuern/octopus-energy-gallery/qr-code.webp" alt="Octopus Energy QR Code" class="grid-w100" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Falls dich die Preisgestaltung von &lt;strong&gt;&lt;a href="https://share.octopusenergy.de/tulip-eel-28" target="_blank" rel="noopener noreferrer"&gt;Octopus Energy &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt; anspricht, scanne einfach den QR-Code und sichere dir 100 EUR Guthaben auf den Jahresbeitrag. Ich erhalte dann 50 EUR auf meinen Jahresbeitrag - oder mit anderen Worten: 175 kWh frei &amp;#x1f60e;!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://www.zendure.de" target="_blank" rel="noopener noreferrer"&gt;Zendure &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>pypaperless v4 und Home Assistant Integration</title><link href="https://tbsch.de/post/2025-05-26-pypaperless-v4-und-home-assistant-integration/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2025-05-26-pypaperless-v4-und-home-assistant-integration/</id><published>2025-05-26T00:00:00Z</published><updated>2025-05-26T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="news"/><category term="home-assistant"/><category term="paperless"/><category term="projekt"/><category term="python"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2025-05-26-pypaperless-v4-und-home-assistant-integration/featured.webp"/><summary type="html">Ich habe pypaperless v4 veröffentlicht. Neuigkeiten zur Home Assistant Integration!</summary><content type="html">&lt;p&gt;Oha, schon wieder ein Major Update &amp;#x1f631;! Wird ja langsam zur Gewohnheit.&lt;/p&gt;
&lt;h2 class="relative group"&gt;pypaperless v4
&lt;div id="pypaperless-v4" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#pypaperless-v4" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Spaß beiseite, die neue Version von &lt;em&gt;pypaperless&lt;/em&gt; bringt Support für &lt;em&gt;Paperless-ngx&lt;/em&gt; ab Version &lt;code&gt;2.15.0&lt;/code&gt; und enthält ein Refactoring der Art und Weise, wie mit &lt;code&gt;CustomField&lt;/code&gt; Objekten umgegangen werden kann. In den kurz darauf erfolgten Minor Updates gab es außerdem haufenweise neue Features.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Home Assistant Integration
&lt;div id="home-assistant-integration" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#home-assistant-integration" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Das mir vorgenommene Ziel einer &lt;em&gt;Home Assistant&lt;/em&gt; Integration rückt nun in greifbare Nähe. Nicht jedoch, weil ich meine eigene Integration zur Marktreife geführt hätte. Dafür fehlte mir leider schlichtweg die Zeit, und aus privaten Gründen könnte ich den notwendigen Support in meiner Freizeit auch in Zukunft gar nicht bewältigen.&lt;/p&gt;
&lt;p&gt;Umso aufgeregter machte mich die &lt;strong&gt;Mail von Florian&lt;/strong&gt;, der mir mitgeteilt hat, selbst eine Integration bauen und gern mit mir gemeinsam daran arbeiten zu wollen.&lt;/p&gt;
&lt;p&gt;Direkt zu den &lt;a href="https://github.com/home-assistant/core/pulls?q=is%3Apr&amp;#43;label%3A%22integration%3A&amp;#43;paperless_ngx%22&amp;#43;is%3Aopen" target="_blank" rel="noopener noreferrer"&gt;Pull Requests &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; von Florian.&lt;/p&gt;
&lt;p&gt;Ich werde hier dann mit einer weiteren News auf den endgültigen Release hinweisen.&lt;/p&gt;
&lt;p&gt;Viel Spaß mit &lt;em&gt;pypaperless&lt;/em&gt; v4 und der neuen &lt;em&gt;Home Assistant&lt;/em&gt; Integration!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@cdr6934?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Chris Ried &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/ein-computerbildschirm-mit-einem-haufen-code-darauf-ieic5Tq8YMk?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Smart Home als Gewohnheitsverstärker</title><link href="https://tbsch.de/post/2025-05-25-smart-home-als-gewohnheitsverst%C3%A4rker/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2025-05-25-smart-home-als-gewohnheitsverst%C3%A4rker/</id><published>2025-05-25T00:00:00Z</published><updated>2025-05-25T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="smart-home"/><category term="gewohnheit"/><category term="home-assistant"/><category term="trigger"/><category term="workflow"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2025-05-25-smart-home-als-gewohnheitsverst%C3%A4rker/featured.webp"/><summary type="html">Smart Home nutzen, um nicht nur das Zuhause zu steuern, sondern Gewohnheiten zu verstärken.</summary><content type="html">&lt;p&gt;Automatisierung ist für viele ein &lt;strong&gt;technisches Hobby&lt;/strong&gt;. Ein Spielplatz, auf dem Regeln und Zustände wie Bausteine zusammengesetzt werden. Ich habe mich lange genau so damit beschäftigt. Aber irgendwann war mir das zu wenig. Warum? Weil mein Ziel nicht nur war, ein paar Lichter automatisch an- und auszuschalten oder die Kaffeemaschine fernzusteuern. Ich wollte, dass Technik mir hilft, &lt;strong&gt;mich selbst zu strukturieren&lt;/strong&gt; – ohne mich zu bevormunden.&lt;/p&gt;
&lt;p&gt;Genau an dieser Stelle wurde &lt;em&gt;Home Assistant&lt;/em&gt; für mich mehr als nur ein zentrales Dashboard. Es wurde ein Werkzeug zur Selbstverstärkung. Oder, anders gesagt: ein Gewohnheitsverstärker &amp;#x1f601;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Von stumpfer Regel zu echtem Kontext
&lt;div id="von-stumpfer-regel-zu-echtem-kontext" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#von-stumpfer-regel-zu-echtem-kontext" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Die klassische Smart-Home-Automation funktioniert nach dem Schema: Wenn Zustand A, dann Aktion B. Wenn Bewegung im Flur, dann Licht an. Wenn Tür geöffnet, dann Alarm deaktivieren. Praktisch, aber &lt;strong&gt;nicht intelligent&lt;/strong&gt;. Diese Automationen denken nicht mit. Sie wissen nichts über meine &lt;strong&gt;Absicht&lt;/strong&gt;, meinen &lt;strong&gt;Tagesplan&lt;/strong&gt; oder meine &lt;strong&gt;Stimmung&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ich habe mich gefragt: Was wäre, wenn Automatisierungen nicht nur Zustände, sondern auch meine Routinen, Ziele oder Gewohnheiten berücksichtigen würden? Was, wenn Technik nicht einfach ausführt, sondern &lt;em&gt;hilft&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;Daraus entstand eine neue Idee. Ich wollte mein Setup nicht mehr nur um Geräte herum bauen, sondern um &lt;em&gt;uns&lt;/em&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Gewohnheit statt Reaktion
&lt;div id="gewohnheit-statt-reaktion" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#gewohnheit-statt-reaktion" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Eine der stärksten Anwendungen für mich war, Automatisierungen nicht mehr nur als Reaktionen auf Umweltveränderungen zu sehen, sondern als Verstärker meiner Gewohnheiten. Damit das gelingt, musst du dich selbst und deine Gewohnheiten sehr genau beobachten.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Beispiel: der sanfte Start in den Tag
&lt;div id="beispiel-der-sanfte-start-in-den-tag" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#beispiel-der-sanfte-start-in-den-tag" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Ich bin ein absoluter Frühaufsteher und schätze &lt;strong&gt;strukturierte Morgenroutine&lt;/strong&gt;. Einfach nur ruhig wach werden, ein bis zwei Kaffee trinken und dann fokussiert in den Tag starten.&lt;/p&gt;
&lt;p&gt;Hier hilft mir &lt;em&gt;Home Assistant&lt;/em&gt; mit einer Automatisierung:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nach dem Aufstehen werden Bewegungen außerhalb des Schlafzimmers registriert, wodurch der Zustand &lt;code&gt;Schlafen: aus&lt;/code&gt; eintritt.&lt;/li&gt;
&lt;li&gt;Die Kaffeemaschine wird eingeschaltet und ist betriebsbereit.&lt;/li&gt;
&lt;li&gt;Sobald ich in meinem Büro Platz genommen habe, werden mir von &lt;em&gt;Alexa&lt;/em&gt; die morgendlichen Meetings vorgelesen, während ich mich einlogge.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Trigger:&lt;/strong&gt; Wir verlassen das Schlafzimmer und bewegen uns in der Wohnung mindestens fünf Minuten. Falls diese Abfolge nicht zutreffen sollte, können wir auch &lt;em&gt;&amp;ldquo;Alexa, guten Morgen&amp;rdquo;&lt;/em&gt; sagen.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Beispiel: entspannt ins Bett gehen
&lt;div id="beispiel-entspannt-ins-bett-gehen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#beispiel-entspannt-ins-bett-gehen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Beim Schlafengehen ist es genau dasselbe, nur wird die Wohnung in den Nachtmodus versetzt und bereitet dafür alles vor.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Im Flur, Treppenhaus und Arbeitszimmer wird der Weg ins Schlafzimmer erleuchtet auf 10%, blaue und lila Farbtöne.&lt;/li&gt;
&lt;li&gt;Wenn wir ins Bett gehen, versetzt das Smart Home die Wohnung in den Zustand &lt;code&gt;Schlafen: laufend&lt;/code&gt;. Alle Lichter schalten sich ab, die Heizung fährt runter.&lt;/li&gt;
&lt;li&gt;Wenn wir eingeschlafen sind, wird die Wohnung in den Zustand &lt;code&gt;Schlafen: an&lt;/code&gt; versetzt. Energiehungrige Geräte werden abgeschaltet, der Alarm wird aktiviert.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Trigger:&lt;/strong&gt; Wir schalten den Fernseher ab, verlassen das Wohnzimmer und betreten den Flur. Falls diese Abfolge nicht zutreffen sollte, können wir auch &lt;em&gt;&amp;ldquo;Alexa, gute Nacht&amp;rdquo;&lt;/em&gt; sagen.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Beispiel: der Pre-Sports-Trigger
&lt;div id="beispiel-der-pre-sports-trigger" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#beispiel-der-pre-sports-trigger" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Ich laufe regelmäßig, weil es mir hilft, den Kopf frei zu bekommen und fit zu bleiben. Bei schlechten Witterungsbedingungen oder im Winter laufe ich vor allem zu Hause auf meinem Laufband.&lt;/p&gt;
&lt;p&gt;Auch hierbei unterstützt mich &lt;em&gt;Home Assistant&lt;/em&gt; mit einer kleinen Automatisierung:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Die Steckdose vom Laufband wird aktiviert und somit das Gerät eingeschaltet.&lt;/li&gt;
&lt;li&gt;Der Raum wird während des Workouts laufend auf Helligkeit überprüft, und ggf. wird die Beleuchtung so eingeschaltet, dass es sonnig wirkt.&lt;/li&gt;
&lt;li&gt;Auf Spotify wird eine Playlist gestartet, die ich extra für das Laufband kuratiert habe - rhythmische Musik als Taktgeber. Direkt über die AirPods.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Trigger:&lt;/strong&gt; Ich muss eine Minute vor oder auf dem Laufband stehen. Diese Zeit nutze ich, um mich zu dehnen und einen Schluck zu trinken.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Automation ≠ Faulheit
&lt;div id="automation--faulheit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#automation--faulheit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;In vielen Diskussionen rund um Smart Home und Automatisierungen schwingt bei Gesprächspartnern (insbesondere Freunde, Verwandte) oftmals ein Missverständnis mit: Dass ich faul wäre. Man könne schließlich immer einmal schnell zum Lichtschalter gehen und diesen betätigen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ich sehe das anders&lt;/strong&gt; und genau darum geht es mir auch gar nicht. Stell dir eine gute Automatisierung einfach wie einen Coach vor, der nicht laut schreit, sondern &lt;em&gt;zur richtigen Zeit am Rand steht und kurz zunickt&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Es geht mir nicht um maximalen Support. Ich will keinen Haushalt, der gänzlich ohne mein Zutun funktioniert. Ich will einen Haushalt, der &lt;em&gt;mich unterstützt&lt;/em&gt; – &lt;strong&gt;still, zuverlässig, respektvoll&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Stolpersteine und Grenzen
&lt;div id="stolpersteine-und-grenzen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#stolpersteine-und-grenzen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Natürlich läuft nicht alles rund. Ich habe viele Automationen zigmal bearbeitet oder auch wieder gelöscht:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Weil sie in unnatürlichen Situationen ausgelöst wurden.&lt;/li&gt;
&lt;li&gt;Weil das Verbinden mit einer Gewohnheit in der Praxis nicht gut funktioniert hat.&lt;/li&gt;
&lt;li&gt;Weil sie technisch zwar clever waren, aber sich nicht gut angefühlt haben.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ein Beispiel: eine Routine, die das Licht im Schlafzimmer beim Aufwachen automatisch als Sonnenaufgang steuern sollte. Klingt harmlos, führte aber regelmäßig dazu, dass beim Schlafen in &lt;strong&gt;unerwünschten Situationen&lt;/strong&gt; das Licht anging. Denn es ist gar nicht so leicht, durch Sensorik herauszufinden, wann wir denn nun wirklich aufstehen &lt;strong&gt;wollen&lt;/strong&gt;. Unsere iPhone-Wecker mit der Automatisierung zu koppeln, klappte leider nur sehr sporadisch - denn häufig stehen wir ohne Wecker auf. Effekt: Frust, nicht Hilfe.&lt;/p&gt;
&lt;p&gt;Was ich gelernt habe: &lt;strong&gt;Automatisierung muss Fehler verzeihen können.&lt;/strong&gt; Sie braucht Kontext. Und sie muss &lt;em&gt;uns&lt;/em&gt; dienen – nicht ihrer eigenen technischen Eleganz.&lt;/p&gt;
&lt;p&gt;Was ich darüber hinaus gelernt habe: immer gute Ausreden für die Frau auf Lager haben, wenn ein Fehlerfall eintritt. Stichwort: &lt;strong&gt;Women Acceptance Factor&lt;/strong&gt; &amp;#x1f604;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Warum das alles?
&lt;div id="warum-das-alles" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#warum-das-alles" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Automatisierungen sind für mich kein Ersatz für Motivation – aber eine &lt;strong&gt;Unterstützung für meine Absicht&lt;/strong&gt;. Sie sind wie Geländer: nicht zwingend nötig, aber hilfreich, wenn man müde ist.&lt;/p&gt;
&lt;p&gt;Gerade das Studieren der eigenen Gewohnheiten, um diese dann mit Technik zu unterstützen, begeistert mich. Es ist sehr zeitaufwendig und man entwickelt nicht jeden Tag etwas Neues, vielmehr ist es der &lt;strong&gt;langfristige Feinschliff&lt;/strong&gt;, der das insgesamt zu einer spannenden Herausforderung macht.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Home Assistant&lt;/em&gt; ist für mich nicht einfach nur ein Smart-Home-System, sondern ein &lt;strong&gt;Werkzeug für ein noch besseres Zuhause&lt;/strong&gt;. Es hilft mir nicht nur, meine Geräte zu steuern, sondern meine Gewohnheiten sanft zu bestärken.&lt;/p&gt;
&lt;p&gt;Es ist ein stiller Begleiter, der mich an gute Routinen erinnert, mir den Beginn eines Trainings angenehmer macht und mir morgens hilft, in den Tag zu finden.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nicht mehr. Aber auch nicht weniger.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@nublson?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Nubelson Fernandes &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/weisses-druckerpapier-neben-schwarzer-computermaus-mY9NpmCwwKE?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Weniger gute Vorsätze, mehr greifbare Ziele</title><link href="https://tbsch.de/post/2025-01-21-weniger-gute-vors%C3%A4tze-mehr-greifbare-ziele/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2025-01-21-weniger-gute-vors%C3%A4tze-mehr-greifbare-ziele/</id><published>2025-01-21T00:00:00Z</published><updated>2025-01-21T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="meinung"/><category term="bericht"/><category term="gewohnheit"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2025-01-21-weniger-gute-vors%C3%A4tze-mehr-greifbare-ziele/featured.webp"/><summary type="html">Meine Meinung zu guten Vorsätzen&amp;hellip; und ein paar Worte zum Thema Motivation.</summary><content type="html">&lt;p&gt;Gerade befinde ich mich wieder einmal auf Geschäftsreise, der Arbeitstag ist überstanden und ich genieße die restlichen Stunden des Tages bei einem kühlen Cocktail und klassischer Musik an der Bar. Warum also nicht einfach ein bisschen schreiben &amp;#x1f604;? Glücklicherweise sind die Tage überstanden, an denen einem jeder ein gutes neues Jahr wünscht und man doch in diesem Jahr seine Ziele und guten Vorsätze erreichen möge. Ja, es ist unser Brauch und die Arbeitskollegen, Freunde und Familienmitglieder meinen es sicher gut. Dennoch halte ich nicht viel davon und mag das gar nicht.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Die guten Vorsätze
&lt;div id="die-guten-vorsätze" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#die-guten-vors%c3%a4tze" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;In meinem Umfeld gibt es sehr viele Menschen, die sich für jedes Neujahr eine Reihe von Self-Optimizing-Maßnahmen oder große Ziele aufbürden, nur um kurz darauf wieder damit zu brechen. Die Gewohnheit ist eben doch so bequem und kuschelig warm-gemütlich.&lt;/p&gt;
&lt;p&gt;Ich möchte mich davon nicht ausnehmen, habe ich mich doch selbst lange genug in diesem Hamsterrad mitgedreht. Vor 15 Jahren fasste ich dann den Entschluss, von guten Vorsätzen auf Abstand zu gehen und einfach &lt;strong&gt;immer&lt;/strong&gt; und ständig an meinen Zielen zu arbeiten. Es ist sehr viel einfacher, seine Ziele auch wirklich zu erreichen, wenn man stetig mit kleinen Schritten voran kommt, als sich den Jahreswechsel für einen kompletten Sinneswandel zum Anlass zu nehmen.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Erfüllung im Job
&lt;div id="erfüllung-im-job" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#erf%c3%bcllung-im-job" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Lange hatte ich überhaupt keine Vorstellung davon, was ich später einmal arbeiten möchte oder was mir Spaß machen könnte. Natürlich war aber die Liste von Dingen, die ich auf keinen Fall tun wollte, sehr lang &amp;#x1f601;. Das machte es mir anfangs schwer, den richtigen Kurs einzuschlagen. Also probierte ich mich durch Einzelhandel und Gastronomie, öffentlichen Dienst und privatwirtschaftliche Verwaltung, Anwendungsentwicklung und IT-Systemintegration, Personalwesen und Controlling, sowie letztendlich Kundenservice für Großunternehmen (Call Center) durch.&lt;/p&gt;
&lt;p&gt;Dass ich letztendlich wieder genau in der IT gelandet bin, obwohl ich mein Hobby niemals zum Beruf machen wollte, ist tatsächlich ein Zufall gewesen. Meine Stärken lagen schon immer in der Datenextraktion, -transformation und -analyse, sowie dem Ziehen von Schlüssen aus den gewonnenen Erkenntnissen und dem Ableiten konkreter Maßnahmen. Das war mein Berufsalltag im Controlling, allerdings mit einfachen Bordmitteln. Nennen wir sie Excel, und ich war so etwas wie der Schöpfer der &lt;em&gt;Excel-Tapeten des Grauens&lt;/em&gt; - so nannte sie zumindest mein damaliger Chef &amp;#x1f604;. Jedoch kam genau diese Tätigkeit immer mehr in Mode, neue Tools und ganze Berufsfelder im Datenbereich entstanden. So konnte ich einen Nutzen aus meinem Wissensvorsprung ziehen und formte das Data Management im Unternehmen federführend mit. Aus heutiger Sicht würde ich genau diesen Moment als größten beruflichen Wegbereiter in meinem Leben bezeichnen.&lt;/p&gt;
&lt;p&gt;Mittlerweile ist es meine Aufgabe, Daten nicht einfach nur zu verstehen, sondern durch ihre Wertschöpfung in die Lage versetzt zu werden, das Unternehmen langfristig effizienter zu machen. Das bedeutet nicht zwangsläufig Personalkosten einzusparen, sondern den Arbeitsalltag meiner Kollegen zu verbessern und ihnen die Möglichkeit zu geben, ihre Arbeitszeit mit wirklich wichtigen Dingen zu verbringen. Davon profitieren am Ende alle: Unternehmen, Kollegen und Kunden. Das ist oft kräftezehrend und anstrengend, aber ich liebe jede einzelne Sekunde meines Berufs und freue mich nach Feierabend schon auf den nächsten Tag. Und das ist, was wirklich zählt, oder?&lt;/p&gt;
&lt;h2 class="relative group"&gt;Bewegen, bewegen, bewegen!
&lt;div id="bewegen-bewegen-bewegen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#bewegen-bewegen-bewegen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Ich möchte gestehen: Ich bin ein Nerd. Das war ich schon immer und werde es vermutlich auch bleiben. Und ich liebe Essen – vor allem ungesund und in großen Mengen &amp;#x1f601;. Perfekte Kombination, oder? Kein Wunder also, dass Kleidergröße M für mich nie gereicht hat. Der erste Schritt, um seine Ziele zu erreichen, ist, einen Missstand zu erkennen und zu überlegen, wie man ihn ändern kann. Die Antwort in meinem Fall ist simpel, wenn auch unbeliebt: Sport machen. Wie bereits erwähnt, bedeutet das, Gewohnheiten zu ändern – und genau das fällt uns Menschen besonders schwer.&lt;/p&gt;
&lt;p&gt;Doch genau hier sah ich eine Gelegenheit, meine beruflichen Skills einzusetzen: Wenn ich Unternehmen verbessern kann, dann sollte das auch mit meinem Bauch ja schließlich gleichermaßen funktionieren. Da es kaum verwertbare Daten zu meinem Verhalten gab, begann ich, mich selbst zu beobachten. Dabei stellte ich fest, dass meine innere Stimme mir ständig Gründe einflüsterte, warum ich keinen Sport machen könnte. Faszinierend, funktioniert aber leider extrem effizient. Also musste ich lernen, jeden dieser Einwände zu entkräften.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ein paar Beispiele:&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Grund&lt;/th&gt;
&lt;th style="text-align: left"&gt;Konter&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Du wirst schwitzen. Schweiß ist ekelhaft, nass und klebt.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Jeder Tropfen steht für maximalen Erfolg!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Du wirst keine Luft bekommen.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Zwei Wochen durchhalten, dann die Leistung langsam steigern.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Andere Menschen werden über dich lachen.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Vielleicht. Aber kenne ich die? Also egal.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Ins Fitnessstudio gehen kostet zu viel Zeit.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Stimmt. Also trainiere ich zuhause und im Freien.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Deine Freunde zahlen für das Gym, gehen aber nicht hin.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Stimmt auch, das mache ich besser.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Niemand wird mitmachen und dich unterstützen.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Diejenigen bleiben dann eben unfit und erfolglos, ich nicht.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Wenn es regnet oder kalt ist, ist Laufen doch blöd.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Absolut, deshalb habe ich mir ein Laufband für Zuhause zugelegt.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Du kannst dann nicht mehr essen, was du willst.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Ich mache keine Diät, sondern Sport. Und ich esse dabei einfach weiter, was ich will, dann nehme ich eben langsamer ab.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Diese Liste könnte ich endlos weiterführen – unser Gehirn ist unglaublich kreativ, wenn es darum geht, Ausreden zu finden. Doch worauf es wirklich ankommt, ist die Erkenntnis, dass man jedes negative Gefühl in etwas Positives verwandeln kann. Man muss es nur wollen. Und dann? Einfach in die Laufschuhe steigen, Musik auf die Ohren und loslaufen. Diese Zeit gehört nur dir, du bist frei und kannst das Leben (und idealerweise auch das Handy) einfach mal auf Standby setzen.&lt;/p&gt;
&lt;p&gt;Schon nach kurzer Zeit – bei mir war es nach dem dritten oder vierten Training – wirst du merken, dass dein Körper die Bewegung regelrecht aufsaugt und mehr davon will. Plötzlich geht dir nach einem Kilometer bei 5 km/h nicht mehr die Puste aus. Kein Seitenstechen, keine Erschöpfung, die dir die Beine wegklappen lässt. Und nach vier Wochen ertappst du dich dabei, von einem sechs Kilometer langen Lauf bei 6,5 km/h zurückzukehren und dich nicht zerstört, sondern richtig gut zu fühlen. Also steigerst du dich weiter.&lt;/p&gt;
&lt;p&gt;Und weißt du, was das Beste ist? Nicht, dass du nicht mehr so schnell außer Atem kommst. Nicht, dass die Waage jede Woche ein niedrigeres Gewicht anzeigt. Sondern wenn deine Freunde dich plötzlich auf deine Fortschritte ansprechen und dir Komplimente machen. Wenn sie zugeben, dass sie dachten, du würdest genauso schnell aufgeben wie alle anderen Quatschköpfe, die nur reden und nichts tun. Und das Gefühl, wenn Klamotten wieder passen, die du schon ganz unten im Schrank verstaut hattest &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;Das ist keine Fantasie – ich habe mit Lauftraining insgesamt über 55 Kilo abgenommen. Die dafür benötigte Zeit war vermutlich viel geringer, als du dir gerade vorstellst. In unter zwei Jahren habe ich täglich etwa 45-90 Minuten investiert – je nachdem, wie es in meinen Alltag passte. Lass einfach mal TikTok weg, dann hast du die Zeit locker. Der Schlüssel zum Erfolg? Kontinuität, nicht Diät. Ich esse, was ich will, so viel ich will – und wenn es mal zu viel war, laufe ich einfach eine Extrameile. Essen ist für mich Lebensfreude, und das lasse ich mir nicht nehmen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mein Tipp an dich:&lt;/strong&gt; Bleib einfach am Ball, baue das Training in deinen Tagesablauf ein, entdecke den Spaß daran und konzentriere dich dabei nur auf dich selbst. Der Rest kommt von allein!&lt;/p&gt;
&lt;h2 class="relative group"&gt;Heißer Tipp für Python Devs
&lt;div id="heißer-tipp-für-python-devs" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#hei%c3%9fer-tipp-f%c3%bcr-python-devs" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Abschließend möchte ich noch einen heißen Tipp loswerden, der insbesondere die Python-Devs und Data Analysten unter euch erfreuen könnte. Falls du dich noch mit &lt;em&gt;Jupyter Notebooks&lt;/em&gt; abmühst oder gemeinsam mit deinem Software Architekten überlegst, wie ihr ein &lt;em&gt;Jupyter Notebook&lt;/em&gt; sauber als Task ausführen lassen könntet: &lt;strong&gt;lasst es einfach&lt;/strong&gt;. Ja, ich meine es wirklich ernst.&lt;/p&gt;
&lt;p&gt;Nutzt die Zeit stattdessen effizient und werft einen Blick auf &lt;a href="https://marimo.io" target="_blank" rel="noopener noreferrer"&gt;marimo &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;. Ich hatte das Projekt bereits länger im Visier, weil ich Jupyter einfach nur leid war. Nun setzen wir das im Unternehmen für erste Notebooks ein und sind mit dieser Entscheidung richtig glücklich. Da werden noch viele weitere Notebooks dazukommen.&lt;/p&gt;
&lt;p&gt;Richte deinen Dank gern per Mail an mich &amp;#x1f604;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von mir, Silvester 2024/2025&lt;/p&gt;</content></entry><entry><title>Aktivierung von Home Assistant Szenen verfolgen - Part 2</title><link href="https://tbsch.de/post/2024-09-25-aktivierung-von-home-assistant-szenen-verfolgen-part-2/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-09-25-aktivierung-von-home-assistant-szenen-verfolgen-part-2/</id><published>2024-09-25T00:00:00Z</published><updated>2024-09-25T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="smart-home"/><category term="guide"/><category term="home-assistant"/><category term="licht"/><category term="sensor"/><category term="szene"/><category term="trigger"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-09-25-aktivierung-von-home-assistant-szenen-verfolgen-part-2/featured.webp"/><summary type="html">Aktivieren und Deaktivieren von Szenen laufend mit einem Sensor verfolgen.</summary><content type="html">&lt;p&gt;Im &lt;a href="/post/2024-09-16-aktivierung-von-home-assistant-szenen-verfolgen-part-1/"&gt;vorherigen Part&lt;/a&gt; habe ich die Lichtszenen und deren Aktivierung beschrieben. Diesmal möchte ich tiefer in das Konzept des Trigger-basierten Template Sensors eintauchen und zeigen, wie dieser verwendet werden kann, um komplexere Szenarien in &lt;em&gt;Home Assistant&lt;/em&gt; zu handhaben.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Stand der Dinge
&lt;div id="stand-der-dinge" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#stand-der-dinge" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Rufen wir uns doch noch einmal eine verkürzte Version meines Sensors in Erinnerung:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;trigger&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;homeassistant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;event&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event_type&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;call_service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event_data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;domain&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;scene&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;service&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;turn_on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;action&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;variables&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;history&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ ... }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;sensor&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;scene_history_wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;unique_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;sensor_scene_history_wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ state_attr(history.wohnzimmer[0], &amp;#34;name&amp;#34;) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;attributes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;current&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ history.wohnzimmer[0] }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;history&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ history.wohnzimmer[1:] }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# ... weitere Räume einfügen&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Bei jedem Start von &lt;em&gt;Home Assistant&lt;/em&gt; sowie jeder Aktivierung einer Szene wird die Aktualisierung des Trigger-basierten Template Sensors ausgelöst. Zuerst werden die &lt;strong&gt;Actions&lt;/strong&gt; abgearbeitet, die in meinem Fall die Variable &lt;code&gt;history&lt;/code&gt; mit Daten für alle Räume füllen. Danach werden die &lt;strong&gt;Sensor&lt;/strong&gt;-Konfigurationen nacheinander ausgeführt.&lt;/p&gt;
&lt;pre class="not-prose mermaid"&gt;
graph LR
A[/Trigger/] --&gt; B(Actions ausführen) --&gt; C[Sensoren aktualisieren]
&lt;/pre&gt;
&lt;p&gt;Während also der &lt;code&gt;scene_history_wohnzimmer&lt;/code&gt; Sensor aktualisiert wird, steht die &lt;code&gt;history&lt;/code&gt; Variable bereits mit allen Werten für das Wohnzimmer zur Verfügung. Diese Tatsache müssen wir im Kopf behalten, wenn wir solche Sensoren bauen. Das gilt natürlich auch für die Sensoren aller weiteren Räume, die wir an unseren Trigger anheften.&lt;/p&gt;
&lt;p&gt;Und hier liegt ein kleines Detail versteckt: sobald die &lt;code&gt;history&lt;/code&gt; Variable nach Auslösen des Triggers für alle Räume befüllt wird, kann sie nämlich die Sensordaten aller Räume aktualisieren - quasi in einem Durchlauf. Ja, so werden auch die Sensoren der Räume aktualisiert, in denen gerade keine Szene aktiviert wurde. Das werden wir aber später noch brauchen &amp;#x1f601;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Herausforderung
&lt;div id="herausforderung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#herausforderung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wir haben es im &lt;a href="/post/2024-09-16-aktivierung-von-home-assistant-szenen-verfolgen-part-1/"&gt;ersten Part&lt;/a&gt; erfolgreich geschafft, dass der Name der zuletzt aktivierten Szene im &lt;em&gt;Scene-History&lt;/em&gt;-Sensor gespeichert wird. Konkret stand der Sensor auf &lt;code&gt;Essen&lt;/code&gt; und verhinderte somit, dass während des Essens die Wohnzimmer-Beleuchtung gedimmt wird, wenn jemand den Fernseher einschaltet.&lt;/p&gt;
&lt;p&gt;Doch was passiert nun, wenn das Licht zwischenzeitlich ausgeschaltet wird? Du ahnst es vermutlich schon: Nichts. Die letzte Szene &lt;code&gt;Essen&lt;/code&gt; wird so lange beibehalten, bis eine andere Szene im Wohnzimmer aktiviert wird. Und hier endet die Geschichte auch schon. Dies wird in anderen Situationen dafür sorgen, dass Automatisierungen eine Szene vermuten und entsprechend reagieren, obwohl sie mittlerweile gar nicht mehr aktiv sein könnte.&lt;/p&gt;
&lt;p&gt;Um dieses Problem zu lösen, erweitern wir nun unseren &lt;em&gt;Scene-History&lt;/em&gt;-Sensor um weitere Trigger und Attribute.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Erweiterung des Sensors
&lt;div id="erweiterung-des-sensors" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#erweiterung-des-sensors" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wir fügen einen weiteren &lt;strong&gt;Trigger&lt;/strong&gt;, ein neues &lt;strong&gt;Attribut&lt;/strong&gt; und ein &lt;strong&gt;Makro&lt;/strong&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; hinzu.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Trigger
&lt;div id="trigger" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#trigger" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Ich teile den Triggern nun auch &lt;em&gt;Trigger-IDs&lt;/em&gt; zu, um innerhalb des Trigger-basierten Template Sensors prüfen zu können, durch welches Ereignis er eigentlich aktualisiert wird. Entitäten wie &lt;code&gt;light.wohnzimmer_lights&lt;/code&gt; gibt es bei mir für jeden Raum, sie gruppieren sämtliche Lampen innerhalb eines Raumes. Das ermöglicht mir die extrem bequeme Abfrage des Beleuchtungsstatus, oder eben alle Lichter gleichzeitig auszuschalten.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;trigger&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;homeassistant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;event&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event_type&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;call_service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event_data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;domain&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;scene&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;service&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;turn_on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;scene_activated&lt;/span&gt; &lt;span style="color:#75715e"&gt;# das ist neu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# und ein neuer Trigger&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;light.wohnzimmer_lights&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;from&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;on&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;to&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;off&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;off_again&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;Attribut
&lt;div id="attribut" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#attribut" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Statten wir den &lt;em&gt;Scene-History&lt;/em&gt;-Sensor im Wohnzimmer nun mit dem Attribut aus, welches in Zukunft die Information vorhält, ob das Licht nach dem Aktivieren einer Szene wieder ausgeschaltet wurde.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;scene_history_wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;unique_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;sensor_scene_history_wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ state_attr(history.wohnzimmer[0], &amp;#34;name&amp;#34;) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;attributes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;current&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ history.wohnzimmer[0] }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;history&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ history.wohnzimmer[1:] }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# das kommt dazu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;off_again&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% from &amp;#34;scenes.jinja&amp;#34; import get_off_again %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ get_off_again(&amp;#34;wohnzimmer&amp;#34;, trigger) }}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Ich habe mich für den Namen &lt;code&gt;off_again&lt;/code&gt; entschieden. Das Template des Attributs importiert ein &lt;strong&gt;Makro&lt;/strong&gt; und führt es dann aus. Damit ich das Template der Funktion &lt;code&gt;get_off_again&lt;/code&gt; auch für andere Räume benutzen kann, ohne es immer wieder kopieren zu müssen, habe ich es in eben jenem Makro ausgelagert. Das ist übrigens der übliche Use-Case für Makros, falls du dich schon mal gefragt hast, wozu die eigentlich gut sein sollen &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;An das &lt;strong&gt;Makro&lt;/strong&gt; übergebe ich den gewünschten Raum und das gesamte &lt;code&gt;trigger&lt;/code&gt; Objekt, welches von &lt;em&gt;Home Assistant&lt;/em&gt; zur Verfügung gestellt wird. In diesem Objekt enthalten ist auch die Information, welcher Trigger ausgelöst wurde.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;An dieser Stelle machen wir uns die Tatsache zu Nutze, dass beim Auslösen eines Triggers immer &lt;strong&gt;State&lt;/strong&gt; und &lt;strong&gt;Attribute&lt;/strong&gt; des Trigger-basierten Template Sensors aktualisiert werden. Das musst du dir stets im Hinterkopf behalten, denn auch unser &lt;strong&gt;Makro&lt;/strong&gt; ist darauf ausgelegt.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;Makro
&lt;div id="makro" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#makro" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Um eigene &lt;strong&gt;Makros&lt;/strong&gt; zu verwenden, erstelle im &lt;code&gt;config&lt;/code&gt;-Ordner deiner &lt;em&gt;Home Assistant&lt;/em&gt; Installation den Unterordner &lt;code&gt;custom_templates&lt;/code&gt;. Hier legst du deine &lt;em&gt;.jinja&lt;/em&gt;-Dateien ab. Ich habe mich für den Dateinamen &lt;code&gt;scenes.jinja&lt;/code&gt; entschieden, einfach weil ich es vorteilhaft finde, Informationen thematisch zu strukturieren.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Die Datei hat folgenden Inhalt:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jinja" data-lang="jinja"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;macro&lt;/span&gt; get_off_again&lt;span style="color:#f92672"&gt;(&lt;/span&gt;area&lt;span style="color:#f92672"&gt;,&lt;/span&gt; trigger&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{# eine Szene wurde aktiviert #}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; trigger.id &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;scene_activated&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; areas &lt;span style="color:#f92672"&gt;=&lt;/span&gt; trigger.event.data.service_data.entity_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;area_id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; area &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; areas &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; return &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;no&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;endif&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{# Lampen wurden ausgeschaltet #}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;elif&lt;/span&gt; trigger.id &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;off_again&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; areas &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;area_id&lt;span style="color:#f92672"&gt;(&lt;/span&gt;trigger.entity_id&lt;span style="color:#f92672"&gt;)]&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; area &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; areas &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; return &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;yes&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;endif&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;endif&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{# Nichts von beidem #}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; return &lt;span style="color:#66d9ef"&gt;is&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;defined&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; return &lt;span style="color:#f92672"&gt;=&lt;/span&gt; state_attr&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;sensor.scene_history_&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; area&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;off_again&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;endif&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; return &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;endmacro&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 class="relative group"&gt;Erläuterungen
&lt;div id="erläuterungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#erl%c3%a4uterungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Das &lt;strong&gt;Makro&lt;/strong&gt; wird mit zwei Parametern aufgerufen. Dies ist einerseits &lt;code&gt;area&lt;/code&gt;, die in meinem Beispiel ja auf &lt;code&gt;wohnzimmer&lt;/code&gt; gesetzt ist. Andererseits das &lt;code&gt;trigger&lt;/code&gt; Objekt von &lt;em&gt;Home Assistant&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Wird &lt;strong&gt;eine Szene aktiviert&lt;/strong&gt;, soll überprüft werden, ob die ausgelöste Szene im &lt;code&gt;wohnzimmer&lt;/code&gt; ist. Falls ja, wird &lt;code&gt;off_again&lt;/code&gt; auf &lt;em&gt;no&lt;/em&gt; gesetzt. Dieselbe Logik wende ich an, wenn &lt;strong&gt;Lampen ausgeschaltet&lt;/strong&gt; werden. Es wird überprüft, ob es sich um den gewünschten Raum handelt und falls ja, &lt;code&gt;off_again&lt;/code&gt; auf &lt;em&gt;yes&lt;/em&gt; gesetzt. Du hast richtig gemerkt: wir haben einen Schalter im klassischen Sinne gebaut, der entweder &lt;em&gt;an&lt;/em&gt; oder &lt;em&gt;aus&lt;/em&gt; ist. Macht bis hierher Sinn, oder?&lt;/p&gt;
&lt;p&gt;Für den Fall, dass weder die aktivierte Szene, noch die ausgeschaltete Lampe aus dem &lt;code&gt;wohnzimmer&lt;/code&gt; sind, wird einfach der aktuell eingestellte Wert übernommen. Warum das notwendig ist? Ich habe dir weiter oben einen brennenden Tipp dazu gegeben &amp;#x1f60e;.&lt;/p&gt;
&lt;p&gt;Im letzten Schritt wird der Wert der Variable &lt;code&gt;return&lt;/code&gt; nun zurückgegeben und in der Folge als &lt;code&gt;off_again&lt;/code&gt; Attribut festgelegt.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Abschlussarbeiten
&lt;div id="abschlussarbeiten" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#abschlussarbeiten" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Der &lt;em&gt;Scene-History&lt;/em&gt;-Sensor kann nun nicht nur erfolgreich die zuletzt aktivierte Szene anzeigen, sondern stellt darüber hinaus auch ein Attribut bereit mit der Information, ob das Licht seit Aktivierung einer Szene wieder abgeschaltet wurde. Damit kann die in &lt;a href="/post/2024-09-16-aktivierung-von-home-assistant-szenen-verfolgen-part-1/"&gt;Part 1&lt;/a&gt; aufgebaute Automatisierung nicht nur feststellen, ob die Szene &lt;code&gt;Essen&lt;/code&gt; im Wohnzimmer zuletzt aktiviert wurde, sondern auch, ob das Licht seither wieder ausgeschaltet worden ist.&lt;/p&gt;
&lt;p&gt;Sobald der Fernseher im Wohnzimmer eingeschaltet wird, überprüft die für das Dimmen verantwortliche Automatisierung in Zukunft nicht nur, ob der &lt;em&gt;Scene-History&lt;/em&gt;-Sensor auf &lt;code&gt;Essen&lt;/code&gt; steht, sondern auch, ob das Licht seither wieder abgeschaltet wurde.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;not&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;conditions&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;sensor.scene_history_wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Essen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;sensor.scene_history_wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;attribute&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;off_again&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Jetzt wird die Automatisierung wirklich zuverlässig laufen und das Licht nur im vorgesehenen Moment dimmen &amp;#x1f601;. Wenn du bessere Ideen zu einer möglichen Umsetzung hast, schreib mir gern. Mein Ziel war die Vermeidung der Erstellung von unzähligen &lt;em&gt;Helfern&lt;/em&gt;.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="note"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Note
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Der Trigger-basierte Template Sensor ist von mir so designt, dass einfach weitere Räume hinzugefügt werden können, ohne den ganzen Code immer wieder schreiben zu müssen. Das war auch notwendig, da ich die &lt;em&gt;Scene-History&lt;/em&gt; in sechs verschiedenen Räumen verwende.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In einem der nächsten Beiträge zu &lt;em&gt;Home Assistant&lt;/em&gt; werde ich darüber berichten, wie ich mit Hilfe der &lt;a href="https://www.home-assistant.io/integrations/local_calendar/" target="_blank" rel="noopener noreferrer"&gt;Local calendar &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;, &lt;a href="https://www.home-assistant.io/integrations/todo/" target="_blank" rel="noopener noreferrer"&gt;To-do list &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; und &lt;a href="https://www.home-assistant.io/integrations/roborock/" target="_blank" rel="noopener noreferrer"&gt;Roborock &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; Integrations einen interaktiven Reinigungsplan erstellt habe.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@itsbilalmn?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Bilal Mansuri &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/ein-zimmer-mit-einer-couch-und-einem-tv-EE0DOgXztcY?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Seit der Version &lt;strong&gt;2023.4&lt;/strong&gt; unterstützt &lt;em&gt;Home Assistant&lt;/em&gt; die Erstellung und Wiederverwendung eigener Makros, &lt;a href="https://www.home-assistant.io/blog/2023/04/05/release-20234/" target="_blank" rel="noopener noreferrer"&gt;siehe hier &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry><entry><title>Aktivierung von Home Assistant Szenen verfolgen - Part 1</title><link href="https://tbsch.de/post/2024-09-16-aktivierung-von-home-assistant-szenen-verfolgen-part-1/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-09-16-aktivierung-von-home-assistant-szenen-verfolgen-part-1/</id><published>2024-09-16T00:00:00Z</published><updated>2024-09-16T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="smart-home"/><category term="guide"/><category term="home-assistant"/><category term="licht"/><category term="sensor"/><category term="szene"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-09-16-aktivierung-von-home-assistant-szenen-verfolgen-part-1/featured.webp"/><summary type="html">Die Aktivierung von Szenen laufend mit einem Sensor verfolgen.</summary><content type="html">&lt;p&gt;Es gibt zahlreiche Smart Home Apps, die für nahezu jedes Gerät eine eigene Steuerung bereitstellen. In den meisten dieser Apps lassen sich mittlerweile individuelle Szenen erstellen, mit denen du für eine Gruppe von Geräten einen bestimmten Zustand festlegen kannst, den sie bei Aktivierung automatisch einnehmen. Szenen sind für viele Menschen vermutlich unnötiger Ballast, weil sie damit nichts anfangen können oder wollen. Und dann gibt es da zum Beispiel mich, der sie insbesondere für die heimische Beleuchtung exzessiv einsetzt.&lt;/p&gt;
&lt;p&gt;Wenn es um Licht geht, gibt es aus meiner Sicht keinen Weg an &lt;a href="https://www.philips-hue.com/de-de" target="_blank" rel="noopener noreferrer"&gt;Philips Hue &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; vorbei:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Die Leuchtmittel sind hochwertig. Ich habe seit über 7 Jahren noch Glühbirnen aus der ersten Generation im Einsatz.&lt;/li&gt;
&lt;li&gt;Die Steuerung in &lt;em&gt;Home Assistant&lt;/em&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; funktioniert perfekt.&lt;/li&gt;
&lt;li&gt;Philips Hue funkt mit ZigBee.&lt;/li&gt;
&lt;li&gt;Kein Cloudzwang&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;, alles wird lokal gesteuert.&lt;/li&gt;
&lt;li&gt;Verwendet man die originale &lt;a href="https://amzlink.to/az0UY0AmCc2cn" target="_blank" rel="noopener noreferrer"&gt;Hue Bridge &lt;i class="ti ti-shopping-cart-share" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; vom Hersteller, kann man die Philips Hue App benutzen und hat hierüber Zugriff auf die Lichtszenen-Galerie. Diese Szenen sehen einfach nur klasse aus.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="note"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Note
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Philips Hue erfüllt sämtliche Voraussetzungen für ein Markenprodukt, neben dem guten Namen haben die Leuchtmittel nämlich auch einen stolzen Preis. Im Ausgleich hierfür machen sie jedoch verglichen zu anderen Herstellern sehr viel richtig.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Home Assistant Szenen
&lt;div id="home-assistant-szenen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#home-assistant-szenen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wenn du zur Steuerung deines smarten Zuhauses &lt;em&gt;Home Assistant&lt;/em&gt; einsetzt, ist dir sicher bereits aufgefallen, dass du hier ebenfalls Szenen kreieren kannst. Falls du das noch nicht entdeckt hast, kannst du über den folgenden Link direkt zu den Einstellungen gelangen &amp;#x1f60e;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://my.home-assistant.io/redirect/scenes/"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="low"
alt="Home Assistant Szenen"
src="https://my.home-assistant.io/badges/scenes.svg"
&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Das Tolle an Szenen ist, dass du dir beliebig viele Snapshots deiner Geräte erstellen und immer wieder aufrufen kannst. Der Nachteil von Szenen ist, dass sie stateless sind, also keinen eigenen Zustand besitzen. Es ist zum Beispiel nicht möglich zu überprüfen, welche Szene gerade in einem Moment ausgeführt wird, um beispielsweise in Abhängigkeit dessen in bestimmten Situationen anders reagieren zu können.&lt;/p&gt;
&lt;p&gt;Es wird Zeit für ein praxisnahes Beispiel.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Ausflug ins Wohnzimmer
&lt;div id="ausflug-ins-wohnzimmer" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ausflug-ins-wohnzimmer" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;In unserem Wohnzimmer wird zur Abenddämmerung das Licht automatisch eingeschaltet. In kalten Jahreszeiten nehmen die Lampen darüber hinaus warme Farbtöne an, um einen Ausgleich zum rauen Wetter zu schaffen. Lampen können so viel mehr als nur Licht erzeugen: sie nehmen positiv Einfluss auf unsere Stimmung.&lt;/p&gt;
&lt;p&gt;Schalten wir nun unseren Fernseher ein, wird das Licht gedimmt, damit eine noch gemütlichere Atmosphäre entsteht. Für all diese Umstände habe ich unterschiedliche Szenen gebaut, welche darüber hinaus täglich wechseln. Das klingt bisher recht unkompliziert, oder?&lt;/p&gt;
&lt;p&gt;Wer regelmäßig an Smart Home Automatisierungen bastelt, wird mir jedoch sofort zustimmen, wenn ich behaupte: alltägliche Abläufe sind alles andere als einfach. Sie können extrem komplex sein. Vor allem, wenn Automatisierungen den Bedürfnissen von mehreren Menschen gleichzeitig gerecht werden sollen (Stichwort: &lt;em&gt;Women Acceptance Factor&lt;/em&gt;&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;). Du wirst dieses Wort in meinen Smart Home Beiträgen noch öfter lesen.&lt;/p&gt;
&lt;p&gt;Essen wir beispielsweise zu Abend, soll das Wohnzimmer (welches auch unseren Esstisch beherbergt) hell erleuchtet werden, also die Szene &lt;strong&gt;Essen&lt;/strong&gt; aktiviert werden. Und nun kann es vorkommen, dass der Fernseher eingeschaltet wird. Du hast ja bereits gelesen, was in unserem Fall dann passiert: Das Licht wird gedimmt, und wir essen plötzlich im Dunkeln.&lt;/p&gt;
&lt;p&gt;Es erfordert im weiteren Verlauf eine manuelle Kurskorrektur durch uns, und das kann nerven: vor allem meine Frau. Und dann dauert es nicht mehr lange, bis ich genervt bin; du verstehst sicher. Mein Anspruch an Heimautomatisierung ist, dass sie intelligent genug agiert, um manuelle Interventionen überflüssig zu machen. Das steigert außerdem den WAF enorm - happy wife, happy life &amp;#x1f604;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Automatisierungen zur Intelligenz verhelfen
&lt;div id="automatisierungen-zur-intelligenz-verhelfen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#automatisierungen-zur-intelligenz-verhelfen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Smart Home Automatisierungen machen dein Zuhause smarter, aber es ist wichtig, realistisch zu bleiben: sie sind nicht wirklich intelligent. Sie lösen unter bestimmten Umständen einfach nur eine Aktion aus, selbst wenn es lediglich bedeutet, jeden Tag um 18 Uhr das Licht einzuschalten – das macht häufig gar keinen Sinn. Und während der Essenszeit das Licht zu dimmen, nur weil der Fernseher eingeschaltet wird, ist eben weder smart noch intelligent. Das ist ehrlich gesagt ziemlich dumm.&lt;/p&gt;
&lt;p&gt;Also müssen wir hier ein bisschen nachhelfen. Wie eingangs erwähnt, sind Szenen stateless: Du weißt also weder, ob eine Szene gegenwärtig aktiv ist, noch um welche es sich dabei handelt. Für mich ist es auch keine Option, alle Lampen einzeln auf bestimmte Farben oder Helligkeit zu überprüfen und zu schauen, ob die Parameter zu irgendeiner Szene passen. Denn meine Szenen sind kunterbunt, verwenden alle möglichen Helligkeitsstufen und sind daher schlichtweg nicht oder eben nur mit höllischem Aufwand nachverfolgbar.&lt;/p&gt;
&lt;p&gt;Wie schön wäre es, wenn &lt;em&gt;Home Assistant&lt;/em&gt; eine Funktion mitbringen würde, die uns hier unterstützen könnte? Normalerweise leite ich mit so einem Satz nun die zündende Lösung ein, in diesem Fall gibt es aber wirklich nichts. Zumindest fast nichts. Es gibt &lt;strong&gt;Trigger-basierte Template Sensors&lt;/strong&gt;&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;! Die lösen zwar das eigentliche Problem nicht, jedoch lässt sich mit ihnen etwas bauen, was grundsätzlich intelligentere Entscheidungen möglich machen kann.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Mein Lösungsweg
&lt;div id="mein-lösungsweg" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#mein-l%c3%b6sungsweg" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Nachdem wir nun die Herausforderung erörtert haben, möchte ich meine Lösung vorstellen. Hast du ein ähnliches Problem selbst lösen wollen und einen anderen Weg eingeschlagen? Lass es mich wissen, ich freue mich von dir zu hören!&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="warning"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Warning
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Die folgenden Passagen setzen voraus, dass du dich zumindest etwas mit &lt;em&gt;Home Assistant&lt;/em&gt; Automatisierungen und Templates auskennst. Ohne Basiswissen werden sie nur schwer zu greifen sein. Ich versuche natürlich trotzdem, alles etwas zu veranschaulichen und die Thematik verständlicher zu gestalten. Dennoch ist das eine komplexe Sache.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;Beobachtungen
&lt;div id="beobachtungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#beobachtungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Um eine Herausforderung lösen zu können, müssen wir zunächst beobachten, wie das System in bestimmten Situationen reagiert.&lt;/p&gt;
&lt;p&gt;Fast alle Automatisierungen schalten bei mir keine Lampen direkt ein. Sie aktivieren Szenen, in denen die eigentlichen Beleuchtungseinstellungen definiert sind. Also musste ich herausfinden, was in &lt;em&gt;Home Assistant&lt;/em&gt; passiert, wenn eine Szene aktiviert wird. Hierbei habe ich beobachtet, dass die Szenen-Entität selbst das Aktivierungsdatum als Zustand einnimmt. Das ist hilfreich, denn mit Zustandsänderungen können wiederum Aktionen ausgelöst werden &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;Ich habe allerdings sehr viele Szenen gebaut und müsste jede davon als Trigger-Bedingung verwenden. Würdest du nach dem Erstellen jeder neuen Szene daran denken, deinen Trigger anzupassen? Sehr gut! Ich jedoch leider nicht, daher ist das für mich kein gangbarer Weg. Und auf sämtliche Zustandsänderungen zu triggern, nur um dann überprüfen zu können, ob es sich dabei um eine Szene handelt, ist für mich ebenso keine gescheite Lösung. Zu viel Overhead.&lt;/p&gt;
&lt;p&gt;Statt aktiv auf die Aktivierung einer Szene zu warten, habe ich mir in der Folge angesehen, wie eine Szene denn eigentlich aktiviert wird: über die Aktion &lt;code&gt;scene.turn_on&lt;/code&gt;. Und genau hier habe ich angesetzt, indem ich sämtliche Aufrufe dieser Aktion mitverfolge.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Trigger-basierter Template Sensor
&lt;div id="trigger-basierter-template-sensor" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#trigger-basierter-template-sensor" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Ausgestattet mit diesem Wissen habe ich einen Trigger implementiert, der je einen &lt;em&gt;Scene-History&lt;/em&gt;&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;-Sensor im Arbeits- und Wohnzimmer updaten soll. Das passiert im Detail, wenn eine Szene aktiviert wird:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Die Aktion &lt;code&gt;scene.turn_on&lt;/code&gt; wird verwendet&lt;/li&gt;
&lt;li&gt;Die Variable &lt;code&gt;history&lt;/code&gt; wird deklariert&lt;/li&gt;
&lt;li&gt;Für Arbeits- und Wohnzimmer werden alle Szenen&amp;hellip;
&lt;ol&gt;
&lt;li&gt;abgefragt&lt;/li&gt;
&lt;li&gt;nach Last-Changed-Datum absteigend sortiert&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Die jeweiligen Zustände der Sensoren auf den Namen der Szene gesetzt&lt;/li&gt;
&lt;li&gt;Die Attribute &lt;code&gt;current&lt;/code&gt; und &lt;code&gt;history&lt;/code&gt; befüllt&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;trigger&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;homeassistant&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;platform&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;event&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event_type&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;call_service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;event_data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;domain&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;scene&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;service&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;turn_on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;action&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;variables&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;history&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set areas = [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;arbeitszimmer&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;wohnzimmer&amp;#34; ] %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set data = namespace(scenes=[]) %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% for area in areas %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set scenes = area_entities(area)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | select(&amp;#34;search&amp;#34;, &amp;#34;^scene.&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | expand
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | sort(attribute=&amp;#34;last_changed&amp;#34;, reverse=true)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | map(attribute=&amp;#34;entity_id&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; | list %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% set data.scenes = data.scenes + [scenes] %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {% endfor %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ dict(zip(areas, data.scenes)) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;sensor&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;scene_history_arbeitszimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;unique_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;sensor_scene_history_arbeitszimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ state_attr(history.arbeitszimmer[0], &amp;#34;name&amp;#34;) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;attributes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;current&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ history.arbeitszimmer[0] }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;history&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ history.arbeitszimmer[1:] }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;scene_history_wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;unique_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;sensor_scene_history_wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &amp;gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {{ state_attr(history.wohnzimmer[0], &amp;#34;name&amp;#34;) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;attributes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;current&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ history.wohnzimmer[0] }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;history&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;{{ history.wohnzimmer[1:] }}&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Ist ganz schön viel Template-Code geworden. Der Vorteil hierbei ist jedoch, dass nun mit vergleichsweise wenigen Zeilen weitere Räume hinzugefügt werden können. Man muss sich einfach nur alles schönreden können &amp;#x1f601;.&lt;/p&gt;
&lt;h4 class="relative group"&gt;Erläuterungen
&lt;div id="erläuterungen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#erl%c3%a4uterungen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Der Teil, der die &lt;code&gt;history&lt;/code&gt; Variable mit Daten füllt, ist vermutlich am schwierigsten zu verstehen. Falls du nicht so tief in den technischen Details steckst, keine Sorge: wir gehen das jetzt Zeile für Zeile noch einmal durch.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jinja" data-lang="jinja"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; areas &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;arbeitszimmer&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;wohnzimmer&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; namespace&lt;span style="color:#f92672"&gt;(&lt;/span&gt;scenes&lt;span style="color:#f92672"&gt;=[])&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;An dieser Stelle werden die Räume (Areas) definiert, für die ich die Szenen abrufen möchte. Danach wird noch ein &lt;a href="https://jinja.palletsprojects.com/en/stable/templates/#jinja-globals.namespace" target="_blank" rel="noopener noreferrer"&gt;Namespace &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; für den darauffolgenden Code reserviert.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jinja" data-lang="jinja"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; area &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; areas &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Für alle Räume wiederholen&amp;hellip;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jinja" data-lang="jinja"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; scenes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; area_entities&lt;span style="color:#f92672"&gt;(&lt;/span&gt;area&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;select&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;search&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;^scene.&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;expand&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;attribute&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;last_changed&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; reverse&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;attribute&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;entity_id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In diesem Befehl liegt die eigentliche Magie. Die Funktion &lt;code&gt;area_entities&lt;/code&gt; gibt dir alle Entitäten zurück, die einem bestimmten Raum zugeordnet sind. Diese Liste kann sehr lang werden, weswegen wir mit &lt;code&gt;select&lt;/code&gt; nur nach Entitäten suchen, die eine Szene verkörpern. Mit Hilfe von &lt;code&gt;expand&lt;/code&gt; werden die Entitäten-Objekte quasi ausgepackt, wir erhalten dadurch Zugriff auf ihre einzelnen Attribute, um mit &lt;code&gt;sort&lt;/code&gt; absteigend nach den letzten Änderungen zu sortieren. Da ich mich dazu entschieden habe, in den Sensoren nur die Entitäten-IDs zu speichern, verwerfen wir alle anderen Attribute mit dem &lt;code&gt;map&lt;/code&gt; Befehl. Schlussendlich speichern wir mit &lt;code&gt;list&lt;/code&gt; alle Ergebnisse als Liste.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jinja" data-lang="jinja"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; data.scenes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; data.scenes &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;scenes&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Speichert die lokale &lt;code&gt;scenes&lt;/code&gt; Variable in unserem Namespace.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jinja" data-lang="jinja"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;endfor&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; dict&lt;span style="color:#f92672"&gt;(&lt;/span&gt;zip&lt;span style="color:#f92672"&gt;(&lt;/span&gt;areas&lt;span style="color:#f92672"&gt;,&lt;/span&gt; data.scenes&lt;span style="color:#f92672"&gt;))&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Die Schleife ist an dieser Stelle durchgelaufen, wir verpacken die Ergebnisse nun in einem Dictionary, welches zugleich den Inhalt der &lt;code&gt;history&lt;/code&gt; Variable bildet.&lt;/p&gt;
&lt;h4 class="relative group"&gt;Ergebnis
&lt;div id="ergebnis" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ergebnis" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Hier ist ein Beispiel, wie die fertig modellierten Daten meines Sensors für das Wohnzimmer am Ende aussehen:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Essen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;attributes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;current&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;scene.wohnzimmer_essen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;history&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;scene.wohnzimmer_tv_2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;scene.wohnzimmer_abend_4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;scene.wohnzimmer_hell&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;scene.wohnzimmer_abend_2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;scene.wohnzimmer_abend_3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;scene.wohnzimmer_gedimmt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;scene.wohnzimmer_tv_1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;scene.wohnzimmer_konzentrieren&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Diese Umsetzung muss man erst einmal sacken lassen. Darum möchte ich dir zum Verschnaufen kurz den Hinweis geben, dass &lt;em&gt;Home Assistant&lt;/em&gt; mit einem tollen Tool ausgeliefert wird: den Entwicklerwerkzeugen. Gerade beim Bauen von Templates empfiehlt es sich, diese Werkzeuge rege zu nutzen; hier kann alles ausprobiert werden. Auch mein obiger Code &amp;#x1f604;. Natürlich musst du ihn an deine Bedingungen anpassen, wie Raumnamen.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://my.home-assistant.io/redirect/developer_template/"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="low"
alt="Home Assistant Entwicklerwerkzeuge"
src="https://my.home-assistant.io/badges/developer_template.svg"
&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Abschlussarbeiten
&lt;div id="abschlussarbeiten" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#abschlussarbeiten" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Nachdem wir die Template-Entitäten in den Einstellungen neu geladen haben, stehen die beiden &lt;em&gt;Scene-History&lt;/em&gt;-Sensoren direkt bereit und werden getriggert, sobald Szenen in den jeweiligen Räumen aktiviert werden. Prima!&lt;/p&gt;
&lt;p&gt;Sobald der Fernseher im Wohnzimmer eingeschaltet wird, überprüft die für das Dimmen verantwortliche Automatisierung in Zukunft, ob die &lt;em&gt;Scene-History&lt;/em&gt; auf &lt;code&gt;Essen&lt;/code&gt; steht. Und wenn ja, wird das Licht einfach nicht gedimmt &amp;#x1f60e;.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;not&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;conditions&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;entity_id&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;sensor.scene_history_wohnzimmer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;state&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Essen&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Dann kann ja in Zukunft der Haussegen nicht mehr schief hängen! Oder? Doch was, wenn das Licht ausgeschaltet wird? Bleibt die &lt;em&gt;Scene-History&lt;/em&gt; dann auf &lt;code&gt;Essen&lt;/code&gt; stehen und sorgt das nicht wiederum in der Folge für weiteren Ärger?&lt;/p&gt;
&lt;p&gt;Im nächsten Part zeige ich dir, wie du deinen neuen Trigger-basierten Template Sensor dazu bringst, auch auf ausgeschaltete Lampen zu reagieren.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@itsbilalmn?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Bilal Mansuri &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/ein-zimmer-mit-einer-couch-und-einem-tv-EE0DOgXztcY?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;em&gt;Home Assistant&lt;/em&gt; ist eine Open-Source-Plattform zur zentralen Steuerung und Automatisierung von Smart Home-Geräten. Sie ermöglicht benutzerdefinierte Automatisierungen und unterstützt zahlreiche Geräte, ohne auf Cloud-Dienste angewiesen zu sein.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Viele Hersteller von Smart Home Geräten setzen auf ihre eigenen Cloud Services. Man kann nur mutmaßen, warum eine Internetverbindung für ihren Betrieb benötigt wird; Fakt ist jedoch, dass einige Geräte ohne funktionierende Internetverbindung ihren Dienst verweigern (bspw. die Roborock Saugroboter von Xiaomi). Darum ist Cloudzwang keine gute Sache.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;em&gt;Women Acceptance Factor&lt;/em&gt; (WAF) beschreibt scherzhaft den Grad, in dem technische Lösungen, insbesondere im Smart Home-Bereich, von Frauen akzeptiert werden. Er wird oft genutzt, um auszudrücken, wie gut eine technische Implementierung im Alltag ankommt und ob sie praktisch, einfach und ästhetisch ansprechend genug ist.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;Schau doch einmal in die &lt;em&gt;Home Assistant&lt;/em&gt; &lt;a href="https://www.home-assistant.io/integrations/template/" target="_blank" rel="noopener noreferrer"&gt;Dokumentation &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; rein, denn die Template Sensors werden hier sehr gut erklärt.&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;Mir ist kein besserer Name als &lt;em&gt;Scene-History&lt;/em&gt;-Sensor eingefallen. Schlimmer noch ist die deutsche Übersetzung im &lt;em&gt;Home Assistant&lt;/em&gt; UI: Szenenhistorie &amp;#x1f922;. Wenn du wohlklingendere Ideen hast, freue ich mich über deinen Hinweis.&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry><entry><title>Paperless Guide: Customization</title><link href="https://tbsch.de/post/2024-08-28-paperless-guide-customization/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-08-28-paperless-guide-customization/</id><published>2024-08-28T00:00:00Z</published><updated>2024-08-28T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="home-lab"/><category term="guide"/><category term="paperless"/><category term="python"/><category term="workflow"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-08-28-paperless-guide-customization/featured.webp"/><summary type="html">Das papierlose Büro mit Scripting monitoren und verbessern.</summary><content type="html">&lt;p&gt;Nachdem ich meine grundlegende Arbeitsweise mit &lt;em&gt;Paperless-ngx&lt;/em&gt; nun detailliert vorgestellt habe, möchte ich noch etwas Content für die richtigen Nerds unter uns abliefern. Auf der Seite über &lt;a href="/post/2024-02-11-paperless-guide-classification/"&gt;Klassifizierungen&lt;/a&gt; habe ich ein paar Mal von einer &lt;strong&gt;Middleware&lt;/strong&gt; gesprochen. Eigentlich trifft es das Wort gar nicht richtig, da es in &lt;em&gt;Paperless-ngx&lt;/em&gt; derzeit keine Möglichkeiten gibt, eigene Programmabläufe während der Laufzeit des Systems einzubringen. Und komm mir jetzt nicht mit den neuen Workflows&amp;hellip; das Feature hätte Potenzial, wenn&amp;hellip; ach&amp;hellip; lassen wir das fürs Erste.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Dunkelverarbeitung
&lt;div id="dunkelverarbeitung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dunkelverarbeitung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Na, kennst du das Wort? Gerade im Büro einer größeren Firma werden wir häufig mit diesem Begriff konfrontiert. Es bezeichnet die automatisierte Erledigung wiederkehrender Aufgaben, ohne dass ein Mensch darauf Einfluss nehmen muss. In deinem papierlosen Büro wirst du dich sicher auch immer wieder selbst dabei ertappen, die immer und immer selben Tätigkeiten zu erledigen. Haha, habe ich dich ertappt &amp;#x1f60e;?&lt;/p&gt;
&lt;p&gt;Eigentlich bringt &lt;em&gt;Paperless-ngx&lt;/em&gt; schon viele tolle Möglichkeiten mit, wie zum Beispiel die Auto-Klassifizierung. Wenn es jedoch an die Details geht, müssen wir immer wieder selbst nacharbeiten.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Ein Beispiel
&lt;div id="ein-beispiel" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ein-beispiel" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wenn ich meine allmonatlichen Kontoauszüge an &lt;em&gt;Paperless-ngx&lt;/em&gt; übergebe, sollen sie immer eine Kombination aus Jahr und Monat im Titel tragen: &lt;code&gt;2024/03&lt;/code&gt;. Und zwar nicht des Monats, in dem das Dokument erstellt oder vom &lt;em&gt;Document Consumer&lt;/em&gt; konsumiert wurde, sondern für den Monat, für den der Kontoauszug schlichtweg ist. Ganz einfach.&lt;/p&gt;
&lt;p&gt;Das System generiert keine passenden Titel für meine Kontoauszüge, und manuelle Anpassungen sind oft umständlich, besonders wenn Dokumente über das Share Sheet vom iPhone hochgeladen werden. Und mal im Ernst: möchtest du bei jedem Dokument wirklich noch darüber nachdenken, den Titel anzupassen? Versuche es ruhig. Das klappt sicher anfangs noch gut &amp;#x1f601;. Auf der Zeitachse führt es zu Inkonsistenzen in der Benennung deiner Dokumente.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Paperless Secretary
&lt;div id="paperless-secretary" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#paperless-secretary" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Aus diesem und anderen Gründen erstellte ich für &lt;em&gt;Paperless-ngx&lt;/em&gt; ein Python-Modul namens &lt;strong&gt;pypaperless&lt;/strong&gt;, welches die API anspricht und einem Entwickler die Möglichkeit gibt, Einfluss auf sein DMS zu nehmen.&lt;/p&gt;
&lt;p&gt;Dieses Modul bildet die Grundlage für mein Projekt &lt;strong&gt;Paperless Secretary&lt;/strong&gt;, also einen virtuellen Sekretär, der wiederkehrende Aufgaben für mich erledigt. Meine Aufgabe besteht darin, diese wiederkehrenden Aufgaben zu identifizieren und entsprechende Bearbeitungsregeln zu erstellen.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="warning"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Warning
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;&lt;strong&gt;Bitte beachte,&lt;/strong&gt; dass ich den Secretary zur Zeit nicht öffentlich zur Verfügung stellen kann. Es handelt sich hierbei um eine experimentelle Software in Python, die insbesondere meinen Bedarf abdeckt und bei dir möglicherweise gar nicht funktioniert, schlimmstenfalls deine Daten in &lt;em&gt;Paperless-ngx&lt;/em&gt; durcheinanderbringen könnte.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;Regel für Kontoauszüge
&lt;div id="regel-für-kontoauszüge" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#regel-f%c3%bcr-kontoausz%c3%bcge" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Kommen wir auf mein oben genanntes Beispiel zurück, welches ich wie folgt gelöst habe:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;N26; Kontoauszüge; Titel bearbeiten.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; re
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; pypaperless.models &lt;span style="color:#f92672"&gt;import&lt;/span&gt; Document
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; .base &lt;span style="color:#f92672"&gt;import&lt;/span&gt; Rule
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; .const &lt;span style="color:#f92672"&gt;import&lt;/span&gt; CORRESPONDENT_N26, DOCUMENT_TYPE_KONTOAUSZUG
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;_rule &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Rule(&lt;span style="color:#e6db74"&gt;&amp;#34;N26; Kontoauszüge; Titel =&amp;gt; yyyy/MM (Sparkonto)&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@_rule.condition&lt;/span&gt;(name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;correspondent == N26&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;check_correspondent&lt;/span&gt;(item: Document) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; bool:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; item&lt;span style="color:#f92672"&gt;.&lt;/span&gt;correspondent &lt;span style="color:#f92672"&gt;==&lt;/span&gt; CORRESPONDENT_N26
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@_rule.condition&lt;/span&gt;(name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;document_type == Kontoauszug&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;check_document_type&lt;/span&gt;(item: Document) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; bool:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; item&lt;span style="color:#f92672"&gt;.&lt;/span&gt;document_type &lt;span style="color:#f92672"&gt;==&lt;/span&gt; DOCUMENT_TYPE_KONTOAUSZUG
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 4)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@_rule.condition&lt;/span&gt;(name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;title !~ yyyy/MM&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;check_document&lt;/span&gt;(item: Document) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; bool:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; content &lt;span style="color:#f92672"&gt;=&lt;/span&gt; item&lt;span style="color:#f92672"&gt;.&lt;/span&gt;content &lt;span style="color:#f92672"&gt;or&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Sparkonto&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;in&lt;/span&gt; content:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;^\d&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{4}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/(0[1-9]|1[0-2])\sSparkonto*$&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pattern &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;^\d&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{4}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/(0[1-9]|1[0-2])*$&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; bool(re&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;match&lt;/span&gt;(pattern, item&lt;span style="color:#f92672"&gt;.&lt;/span&gt;title))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 5)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@_rule.action&lt;/span&gt;(name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Apply new document title.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;apply_title&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;, rule: Rule, item: Document) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; bool:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; content &lt;span style="color:#f92672"&gt;=&lt;/span&gt; item&lt;span style="color:#f92672"&gt;.&lt;/span&gt;content &lt;span style="color:#f92672"&gt;or&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;match&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; re&lt;span style="color:#f92672"&gt;.&lt;/span&gt;search(&lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;\d&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{2}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;\.(\d&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{2}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;)\.(\d&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{4}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;) bis \d&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{2}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;\.\1\.\2&amp;#34;&lt;/span&gt;, content)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;match&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; year &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;match&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;group(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; month &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;match&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;group(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; item&lt;span style="color:#f92672"&gt;.&lt;/span&gt;title &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;year&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;month&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Sparkonto&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;in&lt;/span&gt; content:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; item&lt;span style="color:#f92672"&gt;.&lt;/span&gt;title &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; Sparkonto&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 6)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; rule&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dry_run:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; item&lt;span style="color:#f92672"&gt;.&lt;/span&gt;update()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Keine Sorge, sieht schlimmer aus, als es wirklich ist &amp;#x1f604;. Ich habe ein paar Stellen im Code nummeriert und gehe nun einmal kurz darauf ein.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Es wird eine neue &lt;code&gt;Rule&lt;/code&gt; erstellt. Hierbei handelt es sich um eine Klasse, die zum Core des Secretary gehört. Der Secretary verarbeitet solche Regeln dann, indem er sie auf Dokumente in &lt;em&gt;Paperless-ngx&lt;/em&gt; anwendet.&lt;/li&gt;
&lt;li&gt;Der Regel wird eine &lt;code&gt;Condition&lt;/code&gt; angeheftet. Das bedeutet, dass die Regel nur ausgeführt wird, wenn die Bedingung erfüllt wird. Konkret prüft sie also, ob das Dokument von meiner Bank ist.&lt;/li&gt;
&lt;li&gt;Wieder eine &lt;code&gt;Condition&lt;/code&gt;. Diesmal wird überprüft, ob das Dokument ein Kontoauszug ist.&lt;/li&gt;
&lt;li&gt;Die letzte &lt;code&gt;Condition&lt;/code&gt; überprüft, ob der Kontoauszug einen Titel in dem Format &lt;code&gt;yyyy/MM&lt;/code&gt; oder &lt;code&gt;yyyy/MM Sparkonto&lt;/code&gt; hat, so wie ich mir das wünsche. Besser gesagt: ob genau dieser Fall hier nicht zutrifft.&lt;/li&gt;
&lt;li&gt;Jetzt wird die &lt;code&gt;Action&lt;/code&gt; implementiert. Das ist die Aktion, die ausgeführt wird, wenn alle Bedingungen zutreffen. Im Dokument-Inhalt ist bei meiner Bank ein Hinweis enthalten, ob der Kontoauszug für mein Girokonto oder Tagesgeldkonto ist. Deswegen überprüft die Aktion das kurz und bildet dann aus dem Inhalt des Dokuments den korrekten Titel.&lt;/li&gt;
&lt;li&gt;Wenn der Secretary gerade nicht im Testmodus ausgeführt wird, wird der neue Titel dann letztendlich in &lt;em&gt;Paperless-ngx&lt;/em&gt; festgelegt.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Bei der Klasse &lt;code&gt;Document&lt;/code&gt; handelt es sich um ein Objekt von &lt;strong&gt;pypaperless&lt;/strong&gt;. Dieses Objekt stellt nicht nur sämtliche Daten aus &lt;em&gt;Paperless-ngx&lt;/em&gt; bereit, sondern auch Funktionen zum Ändern und Löschen von eben solchen Daten.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Weitere Use-Cases
&lt;div id="weitere-use-cases" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#weitere-use-cases" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Es gibt zahlreiche Anwendungsmöglichkeiten für diese Regeln. In meinem Fall haben sich folgende Use-Cases herauskristallisiert:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Titel von Dokumenten anpassen&lt;/li&gt;
&lt;li&gt;Custom Fields von Dokumenten automatisch befüllen&lt;/li&gt;
&lt;li&gt;Reminder für Wiedervorlagen/Todos&lt;/li&gt;
&lt;li&gt;Verschiedene Validierungen&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ich bin gespannt, welche Herausforderungen du mit diesen Regeln angehen würdest. Teile mir gerne deine Ideen mit!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@cdr6934?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Chris Ried &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/ein-computerbildschirm-mit-einem-haufen-code-darauf-ieic5Tq8YMk?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Eigener Strom mit Balkonkraftwerk</title><link href="https://tbsch.de/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/</id><published>2024-08-20T00:00:00Z</published><updated>2024-08-20T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="smart-home"/><category term="solar"/><category term="energie"/><category term="home-assistant"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/featured.webp"/><summary type="html">Selbst Strom erzeugen und dabei Geld sparen? Ein kleiner Einblick.</summary><content type="html">&lt;div class="lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl"&gt;
Selbst Strom erzeugen und dabei Geld sparen? Ein kleiner Einblick.
&lt;/div&gt;
&lt;p&gt;Du hast sicher schon davon gehört: Seit der Energiekrise 2022 sind &lt;strong&gt;Solaranlagen&lt;/strong&gt; und &lt;strong&gt;Balkonkraftwerke&lt;/strong&gt; in aller Munde. Diese Situation hat uns allen vor Augen geführt, wie abhängig wir von Stromanbietern und dem gesamten System&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; sind. Der Strommarkt in unserem Land ist nicht nur extrem unübersichtlich. Vergleichsportale wie Check24 und Verivox tragen meiner Meinung nach sogar noch zur Verwirrung bei, indem sie die Preise für Verbraucher verzerren.&lt;/p&gt;
&lt;p&gt;In meinem Umfeld begannen plötzlich viele Freunde, Kollegen und Bekannte, Solaranlagen auf ihren Dächern zu installieren und eigenen Strom zu produzieren. Dadurch begann auch ich, mich mit dem Thema auseinanderzusetzen, obwohl ich anfangs skeptisch war. Da ich kein eigenes Haus besitzen möchte und lieber in einer schönen Wohnung lebe, ist es für mich nicht sinnvoll, eine Solaranlage auf dem Dach zu installieren. Daher kam für mich nur ein Balkonkraftwerk infrage.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Was ist ein Balkonkraftwerk&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;?
&lt;div id="was-ist-ein-balkonkraftwerk" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-ist-ein-balkonkraftwerk" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Kurz gesagt: Es sind Solaranlagen, genau wie jene, die du auf den Hausdächern überall sehen kannst. Sie sind einfach kleiner dimensioniert und daher mit weniger Solarmodulen ausgestattet. In der Regel bestehen Balkonkraftwerke aus einem bis sechs Solarmodulen, da aktuell maximal &lt;em&gt;800 Watt&lt;/em&gt; in den Stromkreis eingespeist werden dürfen. Ein großer Vorteil gegenüber Solaranlagen auf Dächern ist, dass Balkonkraftwerke, wie der Name schon sagt, meist am Balkongeländer befestigt werden &amp;#x1f601;. Alternativ kann man sie auch auf den Balkon stellen, im Garten platzieren oder an der Hausfassade anbringen. Letztendlich steckt man sie dann einfach in eine Steckdose. Das macht sie unglaublich flexibel einsetzbar und steigert die Akzeptanz bei Vermietern.&lt;/p&gt;
&lt;p&gt;Ganz simpel formuliert: Ein Balkonkraftwerk besteht aus den Solarmodulen, die Sonnenenergie in Gleichstrom umwandeln, und einem Wechselrichter, der den Gleichstrom in Wechselstrom umwandelt und dann über eine Steckdose in den eigenen Stromkreis einspeist. Wer mag und den Platz dafür hat, stellt sich noch einen Batteriespeicher dazu. Dazu in einem späteren Beitrag mehr.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Meine Anlage
&lt;div id="meine-anlage" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#meine-anlage" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Das nahezu unüberschaubare Angebot an Balkonkraftwerken hat mich zunächst überwältigt, daher habe ich genau überlegt, welche Anlage am besten zu meiner Situation passt. Mein Balkon bietet leider keine idealen Bedingungen für die Anbringung von Solarmodulen, da sich an der Außenseite Halterungen für Blumenkästen befinden. Ein 20kg schweres Solarmodul hätte ich hier niemals aufhängen können. Nach langer Recherche fand ich dann sogenannte Ultraleicht-Module, die 3kg pro Stück wiegen, aber auch ein Quäntchen weniger leisten.&lt;/p&gt;
&lt;p&gt;Außerdem habe ich mir überlegt, was ich mit meinem Balkonkraftwerk erreichen will. Mit einer kleinen Anlage erreicht man zwar keine vollständige Autarkie, aber zumindest möchte ich damit die Grundlast und kleinere Peaks meines Haushalts decken.&lt;/p&gt;
&lt;p&gt;Letztendlich habe ich mich dann hierfür entschieden:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pluginenergy.de/pages/air" target="_blank" rel="noopener noreferrer"&gt;Plugin Energy PiE AIR superLIGHT 780W COMBO &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Wechselrichter: Hoymiles HM-600/700/800-2T&lt;/li&gt;
&lt;li&gt;Selbstgebastelte Aufhängung für Neigungswinkel (und damit mehr Effizienz)&lt;/li&gt;
&lt;li&gt;2 Module nach Südost, 2 Module nach Südwest&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="mpv.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Meine Anlage Südwest"
width="4284"
height="5712"
src="/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/mpv_hu_1dc73fa5ca764b04.webp"
srcset="/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/mpv_hu_1dc73fa5ca764b04.webp 800w, /post/2024-08-20-eigener-strom-mit-balkonkraftwerk/mpv_hu_1c3cd23c1e611365.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/mpv.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ja, du siehst richtig. Diese Ultraleicht-Module lassen sich etwas biegen, was dann perfekt zu meiner Situation passte. Da sie aber sehr wenig Gewicht haben (3kg pro Modul), musste ich meine Konstruktion verstärkt gegen Wind und Sturm absichern. Kann man auf dem Bild nicht richtig erkennen, aber da rührt sich bei einem Windstoß nichts mehr.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Und was bringt es nun?
&lt;div id="und-was-bringt-es-nun" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#und-was-bringt-es-nun" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://pluginenergy.de" target="_blank" rel="noopener noreferrer"&gt;Plugin Energy &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; bewirbt meine Anlage mit einer jährlichen Kostenersparnis von bis zu 235 €. Ich kann also erst in etwa einem Jahr sagen, ob die Jungs und Mädels gut in Mathe sind &amp;#x1f601;.&lt;/p&gt;
&lt;p&gt;Werfen wir einen Blick auf meine anfangs schleppende Entwicklung: Zunächst habe ich mit meiner Anlage deutlich weniger Strom erzeugt, da ich alle vier Module nach Südwesten ausgerichtet hatte &lt;em&gt;(bis zu 1,5 kWh am Tag)&lt;/em&gt;. Nach vier Wochen baute ich noch einmal um, sodass ich je 2 Module nach Südost/Südwest ausgerichtet habe &lt;em&gt;(bis zu 2 kWh am Tag)&lt;/em&gt;. Drei Monate später dann konstruierte ich mir eine Aufhängung, die einen zur Sonne gerichteten Neigungswinkel ermöglicht, mit dem Ergebnis, dass ich den Ertrag massiv steigern konnte &lt;em&gt;(3,5 kWh am Tag war bisher das Maximum, leider war zumeist schlechtes Wetter)&lt;/em&gt; &amp;#x1f60e;.&lt;/p&gt;
&lt;p&gt;Mit &lt;a href="/smart-home/"&gt;Home Assistant&lt;/a&gt; überwache ich jederzeit Stromproduktion und -verbrauch in meinem Haushalt. Sehen wir uns doch einmal den heutigen, eher durchwachsenen und bewölkten Tag an:&lt;/p&gt;
&lt;p&gt;&lt;a href="energieverteilung.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Energieverteilung"
width="596"
height="588"
src="/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/energieverteilung.webp"
srcset="/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/energieverteilung.webp 800w, /post/2024-08-20-eigener-strom-mit-balkonkraftwerk/energieverteilung.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-08-20-eigener-strom-mit-balkonkraftwerk/energieverteilung.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Das Balkonkraftwerk konnte 2,4 kWh Energie gewinnen, von denen ich 0,7 kWh &lt;strong&gt;an den Versorger verloren&lt;/strong&gt; habe. Das passiert immer dann, wenn du mehr Strom erzeugst, als du gerade verbrauchst. Mangels Stromspeicher fließt der überschüssige Strom dann durch den Zähler ins öffentliche Netz. Gut, 0,7 kWh sind sicherlich verschwindend gering und das reicht nicht einmal zum Backen einer Pizza im Ofen. Setzt man das jedoch mit den produzierten 2,4 kWh ins Verhältnis, bedeutet es ganz einfach, dass ich rund 32 % an erzeugter Energie nicht selbst verbrauchen konnte und sie damit verschenkt habe.&lt;/p&gt;
&lt;p&gt;Dem entgegen steht jedoch der Fakt, dass ich 24 % der Stromkosten für den heutigen Tag vermieden habe. Mit anderen Worten: &lt;strong&gt;ein Viertel gespart&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ich möchte in Zukunft noch viele weitere Einblicke in das Leben mit einem Balkonkraftwerk und Home Assistant geben, vielleicht kann ich dir das Thema ja ebenfalls näherbringen! Home Assistant ist eine Open-Source-Software, die es dir ermöglicht, dein Smart Home zentral zu steuern und zu automatisieren. Mit Home Assistant kannst du verschiedene Geräte und Systeme in deinem Haushalt, wie Lampen, Thermostate, Kameras und eben auch dein Balkonkraftwerk, miteinander verknüpfen und über eine einzige App bedienen.&lt;/p&gt;
&lt;p&gt;Wenn du Fragen hast, schreib mir gern.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@chelseadeeyo?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Chelsea &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/blaues-solarpanel-WvusC5M-TM8?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Die organisierte Strompreisbörse EEX, deutsche Energieproduzenten, Stromanbieter und Netzbetreiber inklusive irrwitziger Zuschläge, Steuern und Umlagen.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Den Begriff &lt;em&gt;Balkonkraftwerk&lt;/em&gt; verwende ich lediglich, weil jeder etwas damit anfangen kann. Ich bevorzuge die Bezeichnung &lt;em&gt;Mini PV-Anlage&lt;/em&gt; oder kurz MPV.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry><entry><title>Smart Home Live-Fakten</title><link href="https://tbsch.de/post/2024-05-31-smart-home-live-fakten/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-05-31-smart-home-live-fakten/</id><published>2024-05-31T00:00:00Z</published><updated>2024-05-31T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="news"/><category term="cloudflare"/><category term="webseite"/><category term="workflow"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-05-31-smart-home-live-fakten/featured.webp"/><summary type="html">Eine neue kleine Seite zeigt Live-Fakten zu meiner Smart Home Installation an.</summary><content type="html">&lt;p&gt;Unter &lt;a href="/smart-home/"&gt;diesem Link&lt;/a&gt; steht eine neue kleine Seite bereit, die Live-Fakten zu meiner Smart Home Installation präsentiert. Die Daten werden von einem Key/Value Store abgerufen, der über einen Workflow ca. alle 5 Minuten mit den aktuellen Daten versorgt wird. Darüber hinaus kannst du dir angucken, aus welchen Komponenten mein Setup besteht (mit ein paar schamlosen Verlinkungen) &amp;#x1f601;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Warum?
&lt;div id="warum" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#warum" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Mir ging es dabei weniger um das Präsentieren irgendwelcher Fakten, sondern um die Lösung einer Herausforderung, die ich auch immer wieder im Beruf habe: Wie zur Hölle mache ich Daten abrufbar, die in einem isolierten Bereich liegen? In diesem Fall sprechen wir über die Smart Home Installation innerhalb meines Heimnetzwerkes, die von Inbound-Traffic aus dem Internet, aber auch vor unautorisiertem Traffic innerhalb des Netzwerkes, abgeschirmt ist.&lt;/p&gt;
&lt;p&gt;Die Lösung: Das Smart Home muss die Daten selbst bereitstellen. Auf einer statischen Webseite ohne Datenbanken. Ja, genau&amp;hellip; aber ich habe es nach ein bisschen Grübeln letztendlich hinbekommen &amp;#x1f60e;!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@benceboros?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;BENCE BOROS &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/eingeschaltete-holzkohle-google-home-mini-und-smartphone-anapPhJFRhM?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Paperless Guide: Papierlos mit iPhone</title><link href="https://tbsch.de/post/2024-02-25-paperless-guide-iphone/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-02-25-paperless-guide-iphone/</id><published>2024-02-25T00:00:00Z</published><updated>2025-11-30T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="home-lab"/><category term="guide"/><category term="paperless"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-02-25-paperless-guide-iphone/featured.webp"/><summary type="html">iPhones bereichern unser Leben, auch im privaten Büro sind sie wertvoll.</summary><content type="html">&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="failure"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"&gt;&lt;path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Failure
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Ich werde hier nur über Apple-Produkte berichten. Wenn du sie nicht magst, ist das für mich völlig in Ordnung. Lies einfach nicht weiter. Woran ich nicht interessiert bin, sind Hinweise, warum Apple nicht gut ist oder dass Android ja viel besser sei. Spar dir die Zeit und langweile uns beide damit einfach nicht. Danke &amp;#x1f60e;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Das Smartphone als Werkzeug
&lt;div id="das-smartphone-als-werkzeug" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#das-smartphone-als-werkzeug" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wir haben annähernd alle ein Smartphone in der Tasche und ich persönlich habe zu Social Media und Mobile Games eine Meinung. Die ist gar nicht gut, sparen wir das also besser aus. In meinen Augen wäre es einfach eine Verschwendung, das Smartphone nur für so etwas zu nutzen: denn das ist alles, aber nicht smart.&lt;/p&gt;
&lt;p&gt;Überlege mal. Du hast einen Computer in der Tasche, der mit einigen Laptops konkurrieren kann. Er hat sämtliche Verbindungsmöglichkeiten an Bord, eine Kamera, Sensorik und kann, mit den richtigen Apps ausgestattet, richtig viel Arbeit richtig schnell erledigen. Das ist ein Schweizer Taschenmesser ohne Schneidwerkzeug, aber vielleicht sind Smartphones in Zukunft ja mit einem schneidfähigen Laser ausgestattet. Wenn ich es mir recht überlege: nein, lieber nicht &amp;#x1f601;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Motivation
&lt;div id="motivation" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#motivation" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Alle Pflichten des Lebens haben eine Gemeinsamkeit, da spielt es auch gar keine Rolle, ob es der Papierkram oder regelmäßiges Sporttreiben ist: du machst keine Freudensprünge, wenn du sie erledigen &lt;em&gt;musst&lt;/em&gt;. Ich bin ein Mensch, der gern alle äußeren Umstände abwägt, die mich davon abhalten könnten, etwas zu tun - um sie dann als Ausreden zu nutzen.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Heute ist Regen angesagt?
Oh, wie schade, dann kann ich wohl keine Jogging-Tour machen.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Kommt dir bekannt vor? &amp;#x1f606;&lt;/p&gt;
&lt;p&gt;Kommen wir zurück zu unserem Papierkram. Eine mögliche Barriere war in meinem Fall die Tatsache, dass ich eine Abneigung gegenüber Druckern/Multifunktionsgeräten in meinem Haushalt habe. Die Vorstellung, mit meinem Drucker andauernd irgendwelche Post einscannen zu müssen, hat mich genervt. Ich finde Drucker und insbesondere ihre Software völlig unintuitiv und veraltet, obendrein gibt es Bloatware und Tracker von den Herstellern ohne Ende. Nein danke. Da spielt es auch keine Rolle, ob Canon, HP, Epson oder sonst etwas draufsteht. Es wäre doch schön, wenn mein iPhone bloß vernünftig scannen könnte&amp;hellip; wie war das mit dem Schweizer Taschenmesser?&lt;/p&gt;
&lt;h3 class="relative group"&gt;Digitales Handwerk
&lt;div id="digitales-handwerk" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#digitales-handwerk" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Natürlich hat ein iPhone eine ausgefeilte Scanner-Funktion direkt an Bord, aber &lt;a href="/post/2024-02-18-paperless-guide-workflow/#scannen"&gt;Genius Scan&lt;/a&gt; ist einfach besser. Ich habe absichtlich ein altes Firmenlogo auf dem Papier sichtbar gelassen, da es das Unternehmen eh nicht mehr gibt - auch hier siehst du den qualitativen Unterschied extrem deutlich. Achte doch mal genau auf das Firmenlogo: auf dem zweiten Bild ist der Schriftzug annähernd kerzengerade, obwohl ich das Blatt absichtlich zerknickt habe.&lt;/p&gt;
&lt;div class="width-patch"&gt;&lt;/div&gt;
&lt;div id="gallery-f6ea216cfe32099d379044d068770295" class="gallery"&gt;
&lt;a href="scanned-gallery/ios.webp" class="grid-w50"&gt;&lt;img src="/post/2024-02-25-paperless-guide-iphone/scanned-gallery/ios.webp" alt="Bild: Mit iPhone gescannt" class="grid-w100" /&gt;&lt;/a&gt;
&lt;a href="scanned-gallery/genius.webp" class="grid-w50"&gt;&lt;img src="/post/2024-02-25-paperless-guide-iphone/scanned-gallery/genius.webp" alt="Bild: Mit Genius Scan gescannt" class="grid-w100" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Beide Aufnahmen entstanden im Schwarzweiß-Modus beim Scannen.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Über Geschmackssinn lässt sich nicht streiten. Mir gefällt das zweite Ergebnis besser, da &lt;em&gt;Genius Scan&lt;/em&gt; vielfältige Methoden zur Aufbereitung des Scan-Ergebnisses einsetzt. Dicke schwarze Balken am Rand verschwinden, Schrift und Logo sind klar und es führt Begradigungen in hohem Maße aus.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Dokumente teilen
&lt;div id="dokumente-teilen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dokumente-teilen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Nun sind wir an einem Punkt angelangt, an dem jedes Dokument digital verfügbar ist: egal ob ein Postbrief, ein E-Mail-Anhang oder App-Download. Nun geht es wieder ausschließlich um meine persönlichen Erfahrungen. Es ist daher möglich, dass du meine Schmerzpunkte gar nicht als solche wahrnimmst und gänzlich anderer Meinung bist. Teile sie gern mit mir &amp;#x1f601;!&lt;/p&gt;
&lt;h3 class="relative group"&gt;FTP und WebDAV
&lt;div id="ftp-und-webdav" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ftp-und-webdav" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;In den Beschreibungen zum &lt;a href="/post/2024-02-18-paperless-guide-workflow/#konsumieren"&gt;Workflow&lt;/a&gt; sagte ich, dass deine Aufgabe darin besteht, &lt;em&gt;Paperless-ngx&lt;/em&gt; mit Dokumenten zu füttern. Für mich war von Anfang an klar, dass ich nicht jede Datei einzeln hochladen möchte. Das soll automatisch passieren.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Genius Scan&lt;/em&gt; bringt diverse automatische Exportmöglichkeiten mit, sodass eingescannte Dokumente direkt an den &lt;em&gt;Consumption-Ordner&lt;/em&gt; übermittelt werden können. Eine Zeit lang löste ich das über FTP und später WebDAV. Ich machte mich allerdings von den Verbindungsmöglichkeiten von &lt;em&gt;Genius Scan&lt;/em&gt; abhängig und ertappte mich eines Tages dabei, wie ich ankommende E-Mails über das Share Sheet mit &lt;em&gt;Genius Scan&lt;/em&gt; teilte, damit die App das Dokument an den &lt;em&gt;Consumption-Ordner&lt;/em&gt; überstellen konnte. Das war mir nicht smart genug, weil ich nicht nur einen vermeidbaren Umweg über &lt;em&gt;Genius Scan&lt;/em&gt; gehen, sondern auch einen FTP- bzw. WebDAV-Server betreiben musste.&lt;/p&gt;
&lt;p&gt;Eine zusätzliche Herausforderung war, dass ich in meiner &lt;em&gt;Paperless-ngx&lt;/em&gt; Installation die Dokumente von zwei Personen verwalte. Ich brauchte also auch noch Mandantenfähigkeit bei der Bereitstellung - damals gab es &lt;strong&gt;Workflows&lt;/strong&gt; noch nicht.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Shortcuts
&lt;div id="shortcuts" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#shortcuts" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Wie schön wäre es, wenn ich ein Dokument direkt mit &lt;em&gt;Paperless-ngx&lt;/em&gt; teilen könnte, so wie wir das von Messengern beim Foto-Sharing gewöhnt sind? Und wie geil wäre es, wenn ich gleichzeitig noch festlegen könnte, für welche Person das Dokument bestimmt ist? Genau hier kommen Shortcuts auf Apple-Geräten ins Spiel. Die kann man nämlich komplett an seine Bedürfnisse anpassen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kurzerhand habe ich einen Shortcut mit diesem Flow erstellt:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Eingabe über Share Sheet: Bilder, PDFs, Text, Formatierter Text&lt;/li&gt;
&lt;li&gt;Abfrage, für welche Person das Dokument bestimmt ist&lt;/li&gt;
&lt;li&gt;Aufruf des REST API Endpunktes zum Erstellen neuer Dokumente&lt;/li&gt;
&lt;li&gt;Übermittlung aller geteilten Dokumente&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Diesen Shortcut habe ich dann noch im Share Sheet als Favoriten hinterlegt, sodass er nun an prominenter Stelle mit dem Finger ansteuerbar ist:&lt;/p&gt;
&lt;p&gt;&lt;a href="iphone.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Dokument teilen mit dem iPhone"
width="614"
height="719"
src="/post/2024-02-25-paperless-guide-iphone/iphone.webp"
srcset="/post/2024-02-25-paperless-guide-iphone/iphone.webp 800w, /post/2024-02-25-paperless-guide-iphone/iphone.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-25-paperless-guide-iphone/iphone.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4 class="relative group"&gt;Download
&lt;div id="download" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#download" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Interessiert? Ich teile den Shortcut gern mit dir über iCloud. Konfigurieren musst du ihn lediglich mit deiner &lt;em&gt;Paperless-ngx&lt;/em&gt;-URL und einem Wörterbuch bestehend aus Name/API-Token Paaren. Du kannst mehrere Personen mit ihren jeweiligen Tokens angeben.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.icloud.com/shortcuts/96b126eb7e6f4111b382dbd7011798f4" target="_blank" rel="noopener noreferrer"&gt;https://www.icloud.com/shortcuts/96b126eb7e6f4111b382dbd7011798f4 &lt;i class="ti ti-brand-apple-filled" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 class="relative group"&gt;Abgeheftete Dokumente öffnen
&lt;div id="abgeheftete-dokumente-öffnen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#abgeheftete-dokumente-%c3%b6ffnen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Ich spreche immer davon, Dokumente zu digitalisieren und in &lt;em&gt;Paperless-ngx&lt;/em&gt; zu archivieren. Manchmal möchten oder müssen wir jedoch Dokumente auch im Original aufbewahren. In einem Profi-Tipp über &lt;a href="/post/2024-02-18-paperless-guide-workflow/#qr-codes-erstellen"&gt;dieser Überschrift&lt;/a&gt; erwähnte ich kurz, dass du einen mit ASN kodierten QR Code mit dem iPhone scannen kannst, um das Dokument direkt in &lt;strong&gt;Paperless-ngx&lt;/strong&gt; zu öffnen.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Shortcuts
&lt;div id="shortcuts-1" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#shortcuts-1" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Natürlich gibt es auch hierfür einen Shortcut &amp;#x1f60e; von mir. Der muss lediglich mit der URL deiner &lt;em&gt;Paperless-ngx&lt;/em&gt;-Instanz konfiguriert werden, das war es schon.&lt;/p&gt;
&lt;h4 class="relative group"&gt;Download
&lt;div id="download-1" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#download-1" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.icloud.com/shortcuts/b217abe228ff4428bb65f5205653e205" target="_blank" rel="noopener noreferrer"&gt;https://www.icloud.com/shortcuts/b217abe228ff4428bb65f5205653e205 &lt;i class="ti ti-brand-apple-filled" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@ultralinx?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Oliur &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/silbernes-macbook-und-telefon-auf-weissem-tisch-iv22jzrqkFg?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Paperless Guide: Workflow</title><link href="https://tbsch.de/post/2024-02-18-paperless-guide-workflow/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-02-18-paperless-guide-workflow/</id><published>2024-02-18T00:00:00Z</published><updated>2024-02-18T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="home-lab"/><category term="guide"/><category term="paperless"/><category term="workflow"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-02-18-paperless-guide-workflow/featured.webp"/><summary type="html">Briefe, Faxe, E-Mails und digitale Dokumente im Alltag meistern.</summary><content type="html">&lt;p&gt;Nachdem wir auf den letzten Seiten unser gemeinsames Verständnis zum papierlosen Büro abgeglichen und geschärft haben, wird es Zeit, auf den stinknormalen Alltag zu sprechen zu kommen. Auch &lt;em&gt;Paperless-ngx&lt;/em&gt; wird uns nicht zu Freudensprüngen verleiten, wenn es darum geht, sich um den Papierkram zu kümmern - auch wenn ich diese Illusion gern aufrecht erhalten hätte. Der Unterschied liegt schlicht und ergreifend darin, dass die vierteljährlichen &lt;em&gt;Ich mache Ablage und räume meine Leitz-Ordner auf&lt;/em&gt;-Sonntage durch ein digitalisiertes Büro einfach wegfallen.&lt;/p&gt;
&lt;p&gt;Auch in der offiziellen &lt;a href="https://docs.paperless-ngx.com/usage/#usage-recommended-workflow" target="_blank" rel="noopener noreferrer"&gt;Dokumentation &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; findest du wertvolle Hinweise darauf, wie man &lt;em&gt;Paperless-ngx&lt;/em&gt; nutzen könnte. Du wirst feststellen, dass meine Erläuterungen in einigen Punkten damit übereinstimmen. Nicht etwa weil ich abschreibe, sondern weil die Architektur der Software uns hier einen Weg bereits geebnet hat. Mit welcher Besohlung du diesen Weg gehst, kannst du dir selbst aussuchen - wie bisher auch, sprechen wir nun weiter über mein Schuhwerk.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Arbeitsablauf
&lt;div id="arbeitsablauf" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#arbeitsablauf" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Sehen wir uns einmal den typischen Ablauf mit &lt;em&gt;Paperless-ngx&lt;/em&gt; an, wenn uns im Alltag neue Dokumente erreichen. Hierbei spielt es im Übrigen überhaupt keine Rolle, auf welchem Wege sie das tun; sei es per Post, per E-Mail, als Download aus einer App oder per Fa&amp;hellip; nein, das blöde Wort mit x am Ende ist keine Erwähnung wert &amp;#x1f921;.&lt;/p&gt;
&lt;p&gt;&lt;a href="workflow.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Ablaufdiagramm"
width="663"
height="694"
src="/post/2024-02-18-paperless-guide-workflow/workflow.webp"
srcset="/post/2024-02-18-paperless-guide-workflow/workflow.webp 800w, /post/2024-02-18-paperless-guide-workflow/workflow.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-18-paperless-guide-workflow/workflow.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 class="relative group"&gt;Barcodes und ASN&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;
&lt;div id="barcodes-und-asn" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#barcodes-und-asn" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Dieses Thema spielt bereits beim Scannen eine größere Rolle, weshalb ich an dieser Stelle kurz darauf eingehen möchte.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="note"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Note
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Barcodes und ASN sind komplett optional. Du musst das nicht benutzen, wenn du nicht möchtest. Es kann die Handhabung deines papierlosen Büros in einigen Situationen jedoch vereinfachen, weshalb es sich auf jeden Fall lohnt, einen Blick auf das Feature zu werfen.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;Grundsätzliches zu Barcodes
&lt;div id="grundsätzliches-zu-barcodes" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#grunds%c3%a4tzliches-zu-barcodes" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Paperless-ngx&lt;/em&gt; kommt mit einem eingebauten Barcode-Scanner, welcher zwei tolle Funktionen bereitstellt:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Splitting&lt;/strong&gt;: solltest du viele Dokumente auf einem Stapel haben und diesen auf einmal einscannen, können anhand von Trennblättern mit Barcode die einzelnen Dokumente erkannt werden.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ASN Erkennung&lt;/strong&gt;: Barcodes oder QR Codes können eine ASN&lt;sup id="fnref1:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; kodiert bekommen, welche von &lt;em&gt;Paperless-ngx&lt;/em&gt; erkannt und an das Dokument angefügt wird.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="https://docs.paperless-ngx.com/advanced_usage/#barcodes" target="_blank" rel="noopener noreferrer"&gt;Hier &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; kannst du etwas über das Barcode-Feature von &lt;em&gt;Paperless-ngx&lt;/em&gt; in der offiziellen Dokumentation nachlesen, und &lt;a href="https://docs.paperless-ngx.com/configuration/#barcodes" target="_blank" rel="noopener noreferrer"&gt;hier &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; alles über ihre Konfiguration.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Warum ich mit ASN arbeite
&lt;div id="warum-ich-mit-asn-arbeite" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#warum-ich-mit-asn-arbeite" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Paperless-ngx&lt;/em&gt; und Leitz-Ordner koexistieren in meinem papierlosen Büro, auch wenn das auf den ersten Blick ein Widerspruch ist. Ich &lt;em&gt;arbeite&lt;/em&gt; nur mit den digitalen Abbildern meiner Dokumente, d.h. ich suche und finde sie im DMS, setze Todo-Tags und behalte meinen Posteingang im Blick. Im Leitz-Ordner &lt;em&gt;lagern&lt;/em&gt; die Originale, die ich aufbewahren muss oder will. Den fasse ich ansonsten nur an, um weitere Dokumente einzulagern. Der Großteil der mich erreichenden Post wird nach dem Einscannen vernichtet. Diese Fakten machen für mich den eindeutigen Unterschied.&lt;/p&gt;
&lt;p&gt;ASN sind ein kleiner Helfer, um mich bei meinem &lt;em&gt;dualen System&lt;/em&gt; zu unterstützen. Ich sehe in &lt;em&gt;Paperless-ngx&lt;/em&gt; auf einen Blick, dass ein Dokument als physisches Original existiert und auf den zweiten Blick, in welchem Leitz-Ordner es lagert. Sollte ich ein Original benötigen, kann ich direkt im richtigen Ordner auf die richtige Seite blättern, da die ASN mir verrät, wo im Ordner sich das Dokument befindet (oder zumindest befinden sollte &amp;#x1f601;). Beispiel gefällig?&lt;/p&gt;
&lt;p&gt;&lt;a href="asn.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: ASN"
width="1060"
height="767"
src="/post/2024-02-18-paperless-guide-workflow/asn_hu_888e6c75ca6d15fa.webp"
srcset="/post/2024-02-18-paperless-guide-workflow/asn_hu_888e6c75ca6d15fa.webp 800w, /post/2024-02-18-paperless-guide-workflow/asn.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-18-paperless-guide-workflow/asn.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Das System bietet sehr charmante Suchmöglichkeiten nach Dokumenten mit ASN, und zeigt diese unter dem Dokumenten-Datum gleich an. Dass ein Dokument eine ASN hat, verrät mir, dass ein Original dazu existieren muss. Die ASN selbst verrät mir, wo das Dokument abgeheftet sein muss. Meine Leitz-Ordner sind beschriftet mit dem Nummernbereich der ASNs, die sie enthalten, z.B. &lt;em&gt;1000 - 1499&lt;/em&gt;. Innerhalb des Ordners sind die Dokumente nach ASN aufsteigend abgeheftet, d.h. Dokument &lt;em&gt;1499&lt;/em&gt; finde ich ganz vorne, während die &lt;em&gt;1000&lt;/em&gt; ganz hinten liegt. Einfach, oder?&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="tip"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path fill="currentColor" d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM191.4 .0132C89.44 .3257 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.61 288.9-.2837 191.4 .0132zM192 96.01c-44.13 0-80 35.89-80 79.1C112 184.8 104.8 192 96 192S80 184.8 80 176c0-61.76 50.25-111.1 112-111.1c8.844 0 16 7.159 16 16S200.8 96.01 192 96.01z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Tip
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Es ist nicht nur möglich, vom digitalen Abbild auf ein Original zu schließen. Die abgehefteten Dokumente beklebe ich mit einem QR Code, in den die ASN kodiert ist. Scanne ich mit meinem iPhone diesen QR Code, öffnet sich &lt;em&gt;Paperless-ngx&lt;/em&gt; im Browser und zeigt mir die digitale Version des Dokuments an. Dazu &lt;a href="/post/2024-02-25-paperless-guide-iphone/#abgeheftete-dokumente-öffnen"&gt;hier&lt;/a&gt; mehr.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;QR Codes erstellen
&lt;div id="qr-codes-erstellen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#qr-codes-erstellen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;In den Erläuterungen zum &lt;a href="/post/2024-02-04-paperless-guide-setup/"&gt;Setup&lt;/a&gt; schrieb ich, dass &lt;em&gt;Marvin Gaube&lt;/em&gt; einen großartigen &lt;a href="https://margau.net/posts/2023-04-16-paperless-ngx-asn/" target="_blank" rel="noopener noreferrer"&gt;Artikel &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; verfasst hat. Hier erklärt er auch, wie man sich selbst QR Codes erstellen kann.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Eine kurze Zusammenfassung&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Du benötigst &lt;a href="https://amzlink.to/az00lbL1uBhtk" target="_blank" rel="noopener noreferrer"&gt;L4731 Klebeetiketten &lt;i class="ti ti-shopping-cart-share" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;einen Drucker, ich nutze &lt;a href="https://amzlink.to/az0omweUAV6ET" target="_blank" rel="noopener noreferrer"&gt;Canon PIXMA MG3650S &lt;i class="ti ti-shopping-cart-share" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;die zu druckenden QR Codes im 4731 Layout. Ein paar Beispiele habe ich &lt;a href="start_1.pdf"&gt;hier&lt;/a&gt;, &lt;a href="start_190.pdf"&gt;hier&lt;/a&gt; und &lt;a href="start_379.pdf"&gt;hier&lt;/a&gt; für dich vorbereitet.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Scannen
&lt;div id="scannen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#scannen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wie über dem Schaubild am Anfang dieser Seite erwähnt, erreichen uns Dokumente mittlerweile über alle möglichen Kanäle. Ich präferiere natürlich den digitalen Weg, denn z.B. ein E-Mail-Anhang oder App-Download ist blitzschnell an &lt;em&gt;Paperless-ngx&lt;/em&gt; übergeben. Hierfür musst du nicht einmal das Handy aus der Hand legen. Aus diesem Grund achte ich auch bei Vertragsabschluss mit Serviceanbietern darauf, dass diese schon selbst digital unterwegs sind. Eine monatliche Rechnung für den Internetanschluss per Post ist für mich ein absolutes Tabu. Das hat auch weniger politisch-motivierte grüne Gründe, es passt schlichtweg nicht zu meinem Lifestyle.&lt;/p&gt;
&lt;p&gt;Gerade bei Behörden erfreut sich der Postweg allerdings nach wie vor größter Beliebtheit. In solchen Fällen musst du nach dem Öffnen des Briefs deinen Scanner bemühen. Hier empfiehlt sich ebenfalls das Smartphone, denn es gibt eine richtig gute Scanner-App in den App Stores: &lt;strong&gt;&lt;a href="https://thegrizzlylabs.com/genius-scan/" target="_blank" rel="noopener noreferrer"&gt;Genius Scan &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;2018 gab es die App als Vollversion für 8,99 EUR, heute bietet sie nur noch ein monatliches Abo an. Du benötigst das Abo nicht zwingend, denn in erster Linie willst du Dokumente scannen. Im Abo enthalten ist ein automatischer Export, auch möglich in Richtung &lt;em&gt;Paperless-ngx&lt;/em&gt;. Als iPhone User bist du allerdings mit Shortcuts (Kurzbefehle App) gesegnet: nutze sie &amp;#x1f60e;. Dazu später mehr.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Konsumieren
&lt;div id="konsumieren" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#konsumieren" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Die größte und umfangreichste Komponente von &lt;em&gt;Paperless-ngx&lt;/em&gt; ist vermutlich der &lt;em&gt;Document Consumer&lt;/em&gt;, er ist Herz und Gehirn des ganzen DMS. Und das geht auch gar nicht anders, denn er stellt sämtliche Funktionalitäten zur Dokumentenverarbeitung, OCR&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;, Fehlerbehandlung, Erkennung von Metainformationen, automatischer Klassifizierung und letztlich auch Archivierung bereit.&lt;/p&gt;
&lt;p&gt;Deine Aufgabe als Eigentümer eines papierlosen Büros ist es, den &lt;em&gt;Document Consumer&lt;/em&gt; mit Dokumenten zu füttern. Hierfür werden eine Upload-Maske auf der Webseite, eine REST API, Abholen per IMAP (E-Mail) aus deinem E-Mail-Konto, ein spezieller Upload-Dateiordner und verschiedene Mobile Apps angeboten.&lt;/p&gt;
&lt;div class="width-patch"&gt;&lt;/div&gt;
&lt;div id="gallery-cc4edaed856f3f6863f02ccb1d972736" class="gallery"&gt;
&lt;a href="upload-gallery/folder.webp" class="grid-w50"&gt;&lt;img src="/post/2024-02-18-paperless-guide-workflow/upload-gallery/folder.webp" alt="Bild: Ordner-Upload" class="grid-w100" /&gt;&lt;/a&gt;
&lt;a href="upload-gallery/imap.webp" class="grid-w50"&gt;&lt;img src="/post/2024-02-18-paperless-guide-workflow/upload-gallery/imap.webp" alt="Bild: Download aus E-Mail" class="grid-w100" /&gt;&lt;/a&gt;
&lt;a href="upload-gallery/rest.webp" class="grid-w50"&gt;&lt;img src="/post/2024-02-18-paperless-guide-workflow/upload-gallery/rest.webp" alt="Bild: Upload per REST API" class="grid-w100" /&gt;&lt;/a&gt;
&lt;a href="upload-gallery/web.webp" class="grid-w50"&gt;&lt;img src="/post/2024-02-18-paperless-guide-workflow/upload-gallery/web.webp" alt="Bild: Upload per Webseite" class="grid-w100" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;h3 class="relative group"&gt;Einsteiger: Upload-Dateiordner
&lt;div id="einsteiger-upload-dateiordner" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#einsteiger-upload-dateiordner" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Die wohl einfachste Möglichkeit ist, Dokumente direkt im &lt;em&gt;Consumption&lt;/em&gt;-Ordner bereitzustellen. Dieser Ordner sollte im Netzwerk freigegeben sein, damit Anwender und Geräte darauf zugreifen können. Ein Netzwerk-Scanner könnte dann die eingescannten Seiten sogar direkt in diesem Ordner ablegen.&lt;/p&gt;
&lt;p&gt;Über ein paar Einstellungen bietet &lt;em&gt;Paperless-ngx&lt;/em&gt; außerdem die Möglichkeit, den &lt;em&gt;Consumption&lt;/em&gt;-Ordner ein bisschen nach eigenen Vorlieben zu &lt;a href="https://docs.paperless-ngx.com/configuration/#consume_config" target="_blank" rel="noopener noreferrer"&gt;konfigurieren &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;. In Kombination mit &lt;a href="https://docs.paperless-ngx.com/usage/#consumption-templates" target="_blank" rel="noopener noreferrer"&gt;Verarbeitungsvorlagen &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; können hierdurch sehr viele persönliche Use-Cases abgebildet werden, es sind fast keine Grenzen gesetzt.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Einsteiger: Mobile Apps
&lt;div id="einsteiger-mobile-apps" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#einsteiger-mobile-apps" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Darüber hinaus kannst du dir eine App aus deinem App Store installieren, mit der du Dokumente bereitstellen kannst. Bedenke dabei aber, dass du dich hier von weiteren Drittanbietern abhängig machst. Das sind private Projekte und du läufst jederzeit Gefahr, dass sie nicht mehr weiterentwickelt werden - dieser Gefahr sehen wir uns bereits beim Einsatz von &lt;em&gt;Paperless-ngx&lt;/em&gt; ausgesetzt&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;. Ein weiteres Risiko ist Monetarisierung, denn plötzlich könnte dich deine geliebte App ein wenig Geld kosten, damit du sie weiterhin wie gewohnt benutzen kannst.&lt;/p&gt;
&lt;p&gt;Falls du dir diese Projekte ansehen möchtest, folge &lt;a href="https://github.com/paperless-ngx/paperless-ngx/wiki/Affiliated-Projects" target="_blank" rel="noopener noreferrer"&gt;diesem Link &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Fortgeschrittene: IMAP (E-Mail)
&lt;div id="fortgeschrittene-imap-e-mail" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fortgeschrittene-imap-e-mail" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Weiterhin besteht die Möglichkeit, das eigene E-Mail-Konto völlig automatisiert nach Dokumenten scannen zu lassen. Hierfür stehen spezielle E-Mail-Regeln bereit, über die du beliebig komplexe Suchmuster festlegen kannst, um Dokumente aufzuspüren und abholen zu lassen.&lt;/p&gt;
&lt;p&gt;Meine persönliche Erfahrung ist, dass ich schlichtweg zu wenige Dokumente direkt als E-Mail oder im Anhang erhalte. In den letzten zwei Jahren haben viele meiner Vertragspartner auf App Downloads umgestellt und sehen von einer direkten Übermittlung per E-Mail ab. Aus diesem Grund ist das IMAP Feature für mich persönlich uninteressant geworden, davon abgesehen, dass ich ohnehin nur extrem ungern Zugriff auf mein iCloud-Konto gewähre.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="warning"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Warning
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Du musst deine Login-Daten zum E-Mail-Konto in &lt;em&gt;Paperless-ngx&lt;/em&gt; hinterlegen und setzt es dadurch einem potenziellen Sicherheitsrisiko aus! Benutzt du dein papierloses Büro übers Internet von unterwegs? Dann lass die Finger von diesem Feature, wenn du dich nicht verdammt gut mit IT Security auskennst. Außerdem musst du darauf vertrauen, dass die Urheber von &lt;em&gt;Paperless-ngx&lt;/em&gt; ausschließlich sichere Verfahren zur Authentifizierung am E-Mail-Konto einsetzen. Möchtest du das Risiko eingehen?&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;Profis: REST API
&lt;div id="profis-rest-api" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#profis-rest-api" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Die meisten Anwender werden vermutlich auf den Einsatz der REST API verzichten, ich persönlich stelle jedes Dokument darüber bereit. Das liegt daran, dass ich alles mit dem iPhone oder am Mac erledige: vom Scannen bis zum Teilen mit &lt;em&gt;Paperless-ngx&lt;/em&gt; über das Share Sheet. Leider kann ich nicht einschätzen, welche Möglichkeiten man hier als Android User hat, da ich zu lange von Android weg bin und mittlerweile überhaupt nicht mehr damit klarkomme. Ein paar Eindrücke gefällig?&lt;/p&gt;
&lt;div class="width-patch"&gt;&lt;/div&gt;
&lt;div id="gallery-f30c6fe868f6891db69496d3f896a3f9" class="gallery"&gt;
&lt;a href="share-gallery/iphone.webp" class="grid-w50"&gt;&lt;img src="/post/2024-02-18-paperless-guide-workflow/share-gallery/iphone.webp" alt="Bild: Mit iPhone teilen" class="grid-w100" /&gt;&lt;/a&gt;
&lt;a href="share-gallery/mac.webp" class="grid-w50"&gt;&lt;img src="/post/2024-02-18-paperless-guide-workflow/share-gallery/mac.webp" alt="Bild: Mit MacOS teilen" class="grid-w100" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Du musst beim Thema Konsumieren den für dich praktikabelsten Weg selbst entdecken. Ich habe für mich entdeckt, dass ich die Arbeit einfach gern mit einem Gerät in der Hand erledige, welches ich eh andauernd in der Hand halte: iPhone. Vielleicht ist das ja auch für dich was?&lt;/p&gt;
&lt;h2 class="relative group"&gt;Klassifizieren
&lt;div id="klassifizieren" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#klassifizieren" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Nachdem dein Dokument konsumiert wurde, findest du es im Posteingang wieder. Hierbei handelt es sich nicht um einen klassischen Ordner, sondern eine dieser &lt;em&gt;virtuellen Schubladen&lt;/em&gt;, von denen ich &lt;a href="/post/2024-02-11-paperless-guide-classification/#tagging"&gt;hier&lt;/a&gt; berichtet hatte. Damit das funktioniert, musst du einen Tag lediglich als &lt;em&gt;Posteingangs-Tag&lt;/em&gt; konfigurieren. Nun kannst du das Dokument klassifizieren bzw. dir die Ergebnisse der automatischen Klassifizierung ansehen.&lt;/p&gt;
&lt;p&gt;&lt;a href="classification.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Klassifizieren von Dokumenten"
width="1601"
height="1144"
src="/post/2024-02-18-paperless-guide-workflow/classification_hu_3f7d782bbe12ed9.webp"
srcset="/post/2024-02-18-paperless-guide-workflow/classification_hu_3f7d782bbe12ed9.webp 800w, /post/2024-02-18-paperless-guide-workflow/classification_hu_e965df3850e15b16.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-18-paperless-guide-workflow/classification.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 class="relative group"&gt;Ein erstes Ergebnis
&lt;div id="ein-erstes-ergebnis" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ein-erstes-ergebnis" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Bereits ohne große Konfiguration meiner Entwickler-Installation und mit einem Test-Dokument, welches wirklich kaum verwertbares Material liefert, hat der &lt;em&gt;Document Consumer&lt;/em&gt; diverse Informationen extrahieren können. Aus dem E-Mail-Header hat er z.B. das korrekte Datum ausgelesen, der &lt;em&gt;Dateiname des konsumierten Dokuments&lt;/em&gt; wurde als Titel hinterlegt und der &lt;em&gt;Posteingangs-Tag&lt;/em&gt; wurde angeheftet.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Ich habe &lt;em&gt;Dateiname des konsumierten Dokuments&lt;/em&gt; im vorherigen Absatz absichtlich unterstrichen, da wir an dieser Stelle beachten müssen, dass ich diese E-Mail nicht per E-Mail-Konto-Abruf habe konsumieren lassen. Ich habe die E-Mail in der Druckansicht geöffnet, ein PDF erzeugt und in den &lt;em&gt;Consumption-Ordner&lt;/em&gt; geworfen. Deshalb wurde der Dateiname als Titel des Dokuments gewählt, nicht der E-Mail-Betreff.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 class="relative group"&gt;Auto-Klassifizierung verbessern
&lt;div id="auto-klassifizierung-verbessern" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#auto-klassifizierung-verbessern" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Natürlich willst du nicht bei jedem Dokument die komplette Klassifizierung selbst vornehmen müssen. Wie auf der &lt;a href="/post/2024-02-11-paperless-guide-classification/#erkennungs-algorithmen"&gt;vorherigen Seite&lt;/a&gt; erläutert, hat jeder Korrespondent, Dokumenttyp, Tag und Speicherpfad die Option, Erkennungs-Algorithmen zu verwenden.&lt;/p&gt;
&lt;p&gt;Ich habe beispielhaft zwei Zuweisungsmuster konfiguriert:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;einen Korrespondenten erstellt, der auf die Absenderadresse matcht&lt;/li&gt;
&lt;li&gt;der Dokumenttyp &lt;em&gt;Rechnung&lt;/em&gt; matcht auf das Wort &lt;em&gt;Rechnung&lt;/em&gt; im Text&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Nachdem ich das Test-Dokument nun aus &lt;em&gt;Paperless-ngx&lt;/em&gt; gelöscht und nochmal konsumieren lassen habe, sieht das Ergebnis bereits so aus:&lt;/p&gt;
&lt;p&gt;&lt;a href="auto-classification.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Klassifizierung von Dokumenten"
width="1601"
height="1144"
src="/post/2024-02-18-paperless-guide-workflow/auto-classification_hu_81b7c53851ccad6d.webp"
srcset="/post/2024-02-18-paperless-guide-workflow/auto-classification_hu_81b7c53851ccad6d.webp 800w, /post/2024-02-18-paperless-guide-workflow/auto-classification_hu_c42e19328ffeccb3.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-18-paperless-guide-workflow/auto-classification.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 class="relative group"&gt;Schlussfolgerung
&lt;div id="schlussfolgerung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#schlussfolgerung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Die kontinuierliche Verbesserung der Auto-Klassifizierung sollte ein integraler Bestandteil deiner regelmäßigen Arbeit mit &lt;em&gt;Paperless-ngx&lt;/em&gt; werden. Wenn konsumierte Dokumente nicht automatisch so klassifiziert werden, wie du dir das vorstellst, lohnt sich auf jeden Fall ein Blick in die Einstellungen der Zuweisungsmuster. Dieser Prozess amortisiert sich auf der Zeitachse, da du weniger Zeit in die Verbesserung deiner Auto-Klassifizierung stecken wirst, als in die manuelle Klassifizierung oder Korrektur falscher Ergebnisse. Und denk daran: immer da, wo manuell gearbeitet wird, entstehen auch Fehler &amp;#x1f60e;.&lt;/p&gt;
&lt;p&gt;Bereits beim Anlegen neuer Korrespondenten, Dokumenttypen, Tags und Speicherpfade empfiehlt es sich außerdem, dass du dir bereits Gedanken über die Auto-Klassifizierung machst.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@lucabravo?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Luca Bravo &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/weisse-apple-magic-maus-auf-braunem-tisch-ujhKqutt3f0?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Archive Serial Number, bzw. eindeutige Seriennummer eines Dokuments in deinem Haushalt. Idealerweise fortlaufend.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Optische Texterkennung, &lt;a href="https://de.wikipedia.org/wiki/Texterkennung" target="_blank" rel="noopener noreferrer"&gt;Wikipedia &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Ich habe in der Einführung von Problemen mit &lt;em&gt;paperless-ng&lt;/em&gt; geschrieben, &lt;a href="/post/2024-01-28-paperless-guide-introduction/#die-lösung-paperless-ngx"&gt;siehe hier&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry><entry><title>pypaperless v3 erschienen</title><link href="https://tbsch.de/post/2024-02-18-pypaperless-v3-erschienen/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-02-18-pypaperless-v3-erschienen/</id><published>2024-02-18T00:00:00Z</published><updated>2024-02-18T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="news"/><category term="paperless"/><category term="projekt"/><category term="python"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-02-18-pypaperless-v3-erschienen/featured.webp"/><summary type="html">Ich habe pypaperless v3 veröffentlicht.</summary><content type="html">&lt;p&gt;Oha, schon wieder ein Major Update &amp;#x1f631;!&lt;/p&gt;
&lt;p&gt;Nun, auf ein großes &lt;a href="/post/2023-12-19-pypaperless-v2-erschienen/"&gt;Refactoring&lt;/a&gt; sollte eigentlich nicht direkt wieder eins folgen. Nachdem ich in den letzten Monaten in Sachen Python aber sehr viel dazulernen konnte, war ich extrem unglücklich damit, wie &lt;em&gt;pypaperless&lt;/em&gt; v2 sich entwickelt hat. Die Befehlsaufrufe fühlten sich falsch an, der Code war zu unstrukturiert - insgesamt war ich einfach unzufrieden mit dem Ergebnis.&lt;/p&gt;
&lt;p&gt;Also habe ich mich kurzerhand entschieden, noch einmal komplett von vorne zu beginnen und den Code wieder gänzlich neu zu schreiben. Nun bin ich aber erst einmal zufrieden.&lt;/p&gt;
&lt;p&gt;Vorerst &amp;#x1f604;! Spaß beiseite. Auf Basis von v3 möchte ich nun eine Home Assistant Integration entwickeln.&lt;/p&gt;
&lt;p&gt;Viel Spaß mit &lt;em&gt;pypaperless&lt;/em&gt; v3!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@cdr6934?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Chris Ried &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/ein-computerbildschirm-mit-einem-haufen-code-darauf-ieic5Tq8YMk?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Paperless Guide: Klassifizierung</title><link href="https://tbsch.de/post/2024-02-11-paperless-guide-classification/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-02-11-paperless-guide-classification/</id><published>2024-02-11T00:00:00Z</published><updated>2024-02-11T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="home-lab"/><category term="guide"/><category term="paperless"/><category term="workflow"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-02-11-paperless-guide-classification/featured.webp"/><summary type="html">Dokumente klassifizieren, um sie später sorglos wiederzufinden.</summary><content type="html">&lt;p&gt;Ich gehe davon aus, dass du an dieser Stelle bereits eine laufende &lt;em&gt;Paperless-ngx&lt;/em&gt;-Installation zur Verfügung hast. Falls nicht, ist das gar nicht tragisch: ich möchte die folgenden Themen auf dieser Seite etwas mehr veranschaulichen. Nun drücke ich dem Ganzen auch meinen persönlichen Stempel auf, denn ich spreche von &lt;em&gt;meinen&lt;/em&gt; Erfahrungen - von denen ich hoffe, dass sie dich zumindest einmal inspirieren werden.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Was macht &lt;em&gt;Paperless-ngx&lt;/em&gt;?
&lt;div id="was-macht-paperless-ngx" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-macht-paperless-ngx" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Auf der ersten &lt;a href="/post/2024-01-28-paperless-guide-introduction/"&gt;Seite&lt;/a&gt; sprach ich davon, dass &lt;em&gt;Paperless-ngx&lt;/em&gt; ein DMS ist. Toll, man kann damit also seine Dokumente organisieren. Das können Leitz-Ordner auch &amp;#x1f606;. Ja, die Arbeit eines DMS beginnt eben mit dem Lagern von Dokumenten, genau wie bei einem Leitz-Ordner.&lt;/p&gt;
&lt;p&gt;Das Tolle an einem DMS aber ist, dass es Dokumente eben nicht nur lagern kann. Es kann unter anderem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dokumente klassifizieren (einen Typ festlegen).&lt;/li&gt;
&lt;li&gt;Dokumente nach Absendern ordnen.&lt;/li&gt;
&lt;li&gt;Dokumente markieren (z.B. zur späteren Weiterarbeit).&lt;/li&gt;
&lt;li&gt;Metainformationen bereitstellen.&lt;/li&gt;
&lt;li&gt;Dokumente automatisiert abholen (z.B. vom Scanner, aus E-Mails).&lt;/li&gt;
&lt;li&gt;Dir sogar mitteilen, in welchem Leitz-Ordner ein Dokument physisch abgeheftet wurde.&lt;/li&gt;
&lt;li&gt;und vieles mehr&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nun wird es sicher auch Leitz-Ordner-Profis geben, die mit Post-Its und anderen kleinen Helfern ähnliche Features analog umsetzen können und sich daher fragen: wozu brauche ich ein DMS? Ich bin leider nicht so ein Profi und ich arbeite einfach viel lieber digital &amp;#x1f605;. So habe ich meinen Papierkram nämlich auch außer Haus jederzeit griffbereit in meiner Hosentasche.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Und so sieht &lt;em&gt;Paperless-ngx&lt;/em&gt; aus, wenn man es zum ersten Mal öffnet:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="overview.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Paperless beim ersten Start"
width="1409"
height="950"
src="/post/2024-02-11-paperless-guide-classification/overview_hu_fa4f3b6cb87b3648.webp"
srcset="/post/2024-02-11-paperless-guide-classification/overview_hu_fa4f3b6cb87b3648.webp 800w, /post/2024-02-11-paperless-guide-classification/overview_hu_a8981dc48efbdfa9.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-11-paperless-guide-classification/overview.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 class="relative group"&gt;Klassifizierung
&lt;div id="klassifizierung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#klassifizierung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Das Klassifizieren von Dokumenten deutet eigentlich an, dass man einem Dokument einen Typ zuweist. Ich verstehe darunter allerdings den Gesamtprozess des Anheftens von Metainformationen an ein Dokument. Wenn ich also von Klassifizierung spreche, meine ich nicht nur das Zuweisen eines Dokumenttyps, sondern die Zuweisung aller Metainformationen an ein Dokument: Dokumenttyp, Korrespondent, Speicherpfad, Tags etc.&lt;/p&gt;
&lt;p&gt;&lt;a href="classification.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Klassifizieren von Dokumenten"
width="1601"
height="1144"
src="/post/2024-02-11-paperless-guide-classification/classification_hu_3f7d782bbe12ed9.webp"
srcset="/post/2024-02-11-paperless-guide-classification/classification_hu_3f7d782bbe12ed9.webp 800w, /post/2024-02-11-paperless-guide-classification/classification_hu_e965df3850e15b16.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-11-paperless-guide-classification/classification.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Diese Begrifflichkeiten wirst du nun sehr oft lesen, ich möchte nun näher auf sie eingehen. Auch lohnt sich ein Blick in die offizielle &lt;a href="https://docs.paperless-ngx.com/usage/" target="_blank" rel="noopener noreferrer"&gt;Dokumentation &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Was ist ein Dokument?
&lt;div id="was-ist-ein-dokument" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-ist-ein-dokument" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Ich spreche immer von Dokumenten, doch bislang habe ich nicht erläutert, was genau ich damit meine. Du wirst dir vermutlich denken, dass das ja klar ist. Im Beruf habe ich jedoch beim Digitalisieren der Posteingangsstrecke gemerkt, dass das eben nicht immer so eindeutig ist. Es wird also Zeit für ein bisschen Theorie &amp;#x1f648;.&lt;/p&gt;
&lt;h4 class="relative group"&gt;Fallbeispiel
&lt;div id="fallbeispiel" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fallbeispiel" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Nehmen wir einen praktischen Fall: dich erreicht &lt;strong&gt;ein&lt;/strong&gt; Brief &amp;#x2709;&amp;#xfe0f;. Enthalten sind &lt;strong&gt;vier&lt;/strong&gt; Blatt Papier &amp;#x1f4c3;, die wiederum doppelseitig bedruckt sind; die gesamte Sendung besteht also aus &lt;strong&gt;acht&lt;/strong&gt; bedruckten Seiten &amp;#x1f4c4;. Aus dem Inhalt geht hervor, dass es sich bei sechs Seiten um &lt;strong&gt;zwei&lt;/strong&gt; unterschiedliche Rechnungen (A und B) &amp;#x1f587;&amp;#xfe0f; handelt. Die verbliebenen zwei Seiten sind eine Aufstellung von Leistungspositionen, die als Anlage &amp;#x1f4ca; zu Rechnung B mitgekommen sind.&lt;/p&gt;
&lt;h4 class="relative group"&gt;Analyse
&lt;div id="analyse" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#analyse" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Wie du siehst, nimmt das Thema schnell ungeahnte Komplexität an. Was wäre für dich in diesem Beispiel denn nun &lt;strong&gt;ein&lt;/strong&gt; Dokument? Aus meiner Sicht gibt es zu dieser Fragestellung erst einmal mehrere Antwortmöglichkeiten:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Da alle Seiten in einem Brief verpackt waren, handelt es sich um &lt;strong&gt;ein&lt;/strong&gt; Dokument (= Sendung).&lt;/li&gt;
&lt;li&gt;Hier liegen &lt;strong&gt;zwei&lt;/strong&gt; Dokumente vor, &lt;strong&gt;eine&lt;/strong&gt; Rechnung A und &lt;strong&gt;eine&lt;/strong&gt; weitere Rechnung B nebst Anlage.&lt;/li&gt;
&lt;li&gt;Es handelt sich um &lt;strong&gt;drei&lt;/strong&gt; Dokumente, &lt;strong&gt;zwei&lt;/strong&gt; Rechnungen A + B und &lt;strong&gt;eine&lt;/strong&gt; Anlage.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alle drei Möglichkeiten sind gangbare Wege, so viel sei dazu gesagt. Jede Person definiert ihr eigenes Ablagesystem und muss es natürlich so strukturieren, dass sie selbst im Bedarfsfall die korrekten Dokumente wiederfinden kann. Ich persönlich halte allerdings &lt;strong&gt;Antwort 2&lt;/strong&gt; für die effizienteste Vorgehensweise und setze dies auch selbst so um. Doch warum?&lt;/p&gt;
&lt;h4 class="relative group"&gt;Schlussfolgerung
&lt;div id="schlussfolgerung" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#schlussfolgerung" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h4&gt;
&lt;p&gt;Die erst einmal schnellste Methode ist natürlich &lt;strong&gt;Antwort 1&lt;/strong&gt;: ich packe den Brief aus, scanne ihn ein und lasse ihn in &lt;em&gt;Paperless-ngx&lt;/em&gt; verschwinden. Das funktioniert sehr gut bis zu dem Tag, an dem ich genau diese eine Rechnung B nebst Anlage wiederfinden muss. Durch die Kapselung mehrerer Rechnungen in ein Dokument wird die Suche nämlich unnötig erschwert. Die Zeit, die ich bei der Klassifizierung also eingespart habe, geht bei der längeren Suche locker dreifach wieder verloren.&lt;/p&gt;
&lt;p&gt;Anders verhält es sich mit &lt;strong&gt;Antwort 3&lt;/strong&gt;: hier stecke ich sehr viel Zeit in die Klassifizierung von drei Dokumenten und habe dann alles sauber abgelegt. Doch welchen Vorteil habe ich davon, die Anlage von ihrer eigentlichen Rechnung B zu trennen? Wenn der Tag kommt, an dem ich Rechnung B und ihre passende Anlage wiederfinden muss, suche ich nach zwei Dokumenten im System&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;. Schlimmstenfalls enthält die Rechnung keinen Hinweis darauf, dass ihr eine Anlage beigefügt worden ist, und das hätte die zusätzliche negative Auswirkung, dass wir eine lose Anlage im DMS herumschwirren haben.&lt;/p&gt;
&lt;p&gt;Aus diesen Gründen halte ich &lt;strong&gt;Antwort 2&lt;/strong&gt; für den effizientesten Weg. Die Sendung wird in ihre zwei Rechnungen A + B aufgetrennt und die Anlage zur Rechnung B gepackt. So entstehen in &lt;em&gt;Paperless-ngx&lt;/em&gt; zwei Dokumente mit ihrer jeweils korrekten Klassifizierung. Darüber hinaus ist die Anlage immer direkt mit ihrer Rechnung zusammen auffindbar. Und falls ich einmal nur nach der Anlage suchen muss, kann ich mir sicher sein, dass mich niemand nach der &lt;em&gt;Rechnungsanlage von Datum XY&lt;/em&gt;, sondern immer nach einer Anlage im Kontext einer bestimmten Rechnung fragen wird.&lt;/p&gt;
&lt;p&gt;&lt;a href="documents.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Dokumenten-Ansicht"
width="1601"
height="1144"
src="/post/2024-02-11-paperless-guide-classification/documents_hu_89bf54254d13b058.webp"
srcset="/post/2024-02-11-paperless-guide-classification/documents_hu_89bf54254d13b058.webp 800w, /post/2024-02-11-paperless-guide-classification/documents_hu_dc0ded0fcecb7899.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-11-paperless-guide-classification/documents.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Nach all der Theorie wirst du dich bei genauem Hinsehen nun fragen, warum auf dem Bild Rechnungen und Einzelverbindungsnachweise voneinander getrennt sind. Ich halte einen EVN schlichtweg nicht für eine Rechnungsanlage(*), sondern ein für sich allein stehendes Dokument. Aus der Rechnung ergibt sich für mich auch ohne einen EVN eine Aufgabe: nämlich der Akt der Bezahlung eben dieser.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Zu *) Hierüber kann man streiten, ich änderte zu dem Thema auch selbst andauernd meine Meinung. Letztendlich habe ich mich aber festgelegt und behalte es so bei.&lt;/p&gt;
&lt;p&gt;Hast du andere Erfahrungen gemacht? Lass es mich wissen &amp;#x1f601;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Korrespondent
&lt;div id="korrespondent" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#korrespondent" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Unter Korrespondenten versteht man den Absender von Dokumenten, die dich erreichen. In der anderen Richtung sind Korrespondenten die Empfänger von Dokumenten, die du verschickst.&lt;/p&gt;
&lt;pre class="not-prose mermaid"&gt;
graph TD
A(Korrespondent) --&gt;|Absender| B
B{{Sendung mit Dokumenten}} --&gt;|Empfänger| A
&lt;/pre&gt;
&lt;p&gt;In &lt;em&gt;Paperless-ngx&lt;/em&gt; können wir uns Korrespondenten als virtuelle Schubladen vorstellen, in denen alle Dokumente einer Person oder Firma abgelegt sind. Mit nur einem Klick finden wir alle Dokumente, die einem bestimmten Korrespondenten zugeordnet sind.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Dokumenttyp
&lt;div id="dokumenttyp" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dokumenttyp" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Mit dem Dokumenttyp legst du fest, um was für eine Art Dokument es sich handelt. Hier kann man beliebig granular werden, doch Simplizität schlägt aus meiner Sicht Komplexität. Die Klassifizierung von Dokumenten zu einem Dokumenttyp erfolgt nach Regeln, die wir uns selbst ausdenken und auferlegen müssen. Es sollte uns also auf einen Blick klar sein, was für ein Dokument vor uns liegt und welcher Dokumenttyp das sein könnte.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="warning"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Warning
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Ertappst du dich selbst dabei, wie du immer wieder zwischen mehreren Dokumenttypen schwankst, gebe ich dir einen guten Rat: konsolidiere sie. Wenn selbst du dir als Mensch unsicher bist, wie soll dann &lt;em&gt;Paperless-ngx&lt;/em&gt; den korrekten Dokumenttyp automatisiert für dich erkennen?&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Sehen wir uns alle Dokumente an, die wir im Laufe der Zeit erhalten, kristallisieren sich ein paar Dokumenttypen deutlich heraus.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In meinem Fall sind das diese hier:&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Dokumenttyp&lt;/th&gt;
&lt;th style="text-align: left"&gt;Beschreibung&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Bescheid&lt;/td&gt;
&lt;td style="text-align: left"&gt;Bescheide von Behörden, z.B. Steuerbescheide, Bewilligungen, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Dokument&lt;/td&gt;
&lt;td style="text-align: left"&gt;Abstrakter Typ für Dokumente, die keinem Typ eindeutig zuordenbar sind.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Kontoauszug&lt;/td&gt;
&lt;td style="text-align: left"&gt;Der Name ist Programm, egal ob Girokonto, ETF-Sparplan, Depot.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Korrespondenz&lt;/td&gt;
&lt;td style="text-align: left"&gt;Allgemeine Schriftwechsel, auf die eine Antwort folgen soll, z.B. Beschwerde beim Internetanbieter.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Kündigung&lt;/td&gt;
&lt;td style="text-align: left"&gt;Kündigungen und Kündigungsbestätigungen von Verträgen aller Art.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Lohnabrechnung&lt;/td&gt;
&lt;td style="text-align: left"&gt;Hiermit werden alle monatlichen Lohnzettel klassifiziert.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;LSt-Bescheinigung&lt;/td&gt;
&lt;td style="text-align: left"&gt;Lohnsteuerbescheinigungen kommen in der Regel 1x im Jahr, sind aber wichtig genug für einen eigenen Typ.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;NK-Abrechnung&lt;/td&gt;
&lt;td style="text-align: left"&gt;Lange habe ich Nebenkostenabrechnungen einfach als &lt;em&gt;Rechnung&lt;/em&gt; klassifiziert, zur schnelleren Auffindbarkeit habe ich aber dann einen eigenen Dokumenttyp erstellt.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Rechnung&lt;/td&gt;
&lt;td style="text-align: left"&gt;Enthält alle Rechnungen, z.B. vom Internetanbieter, Mobilfunk, Käufe mit Garantie, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Spendennachweis&lt;/td&gt;
&lt;td style="text-align: left"&gt;Ich spende jedes Jahr, die Quittungen erhalten diesen Dokumenttyp.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Spesenabrechnung&lt;/td&gt;
&lt;td style="text-align: left"&gt;Beruflich bin ich viel unterwegs und dieser Dokumenttyp enthält die Abrechnungen gegenüber meiner Arbeitgeberin, wie auch ihre Antworten darauf.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;SV-Mitteilung&lt;/td&gt;
&lt;td style="text-align: left"&gt;Bestimmt für Sozialversicherungsmitteilungen, An- und Abmeldungen.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Vertrag&lt;/td&gt;
&lt;td style="text-align: left"&gt;Komplexer Dokumenttyp, enthält Verträge aller Art. Auch Versicherungspolicen und Vertragsänderungsmitteilungen.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Zeitnachweis&lt;/td&gt;
&lt;td style="text-align: left"&gt;Lohnabrechnungen und Zeitnachweise klassifiziere ich getrennt voneinander. Enthält auch Zeitnachweise für Freelancer-Tätigkeiten.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Zertifikat&lt;/td&gt;
&lt;td style="text-align: left"&gt;Nachweise über Schulungen, Weiterbildungen und Seminare.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Zeugnis&lt;/td&gt;
&lt;td style="text-align: left"&gt;Dokumenttyp für Schul-, Ausbildungs- und Arbeitszeugnisse.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 class="relative group"&gt;Tagging
&lt;div id="tagging" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#tagging" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Die einen lieben sie, die anderen hassen sie, und die übrigen 80% nutzen sie nicht: Tags. Auch ich selbst habe mich lange vor dem Einsatz von Tags gesträubt, weil es Dingen eine Komplexität verleihen kann, die schnell unüberschaubar ist. Denn zu jedem Tag gibt es eine Story: wann nutze ich ihn? Wann muss er wieder entfernt werden? Was sagt er aus? Hier sind uns überhaupt keine Grenzen gesetzt.&lt;/p&gt;
&lt;p&gt;Tagging ist prima: bei &lt;em&gt;Paperless-ngx&lt;/em&gt; kann man einem Dokument damit einen Kontext verleihen, oder sogar mehrere. Ähnlich wie bei Korrespondenten kann man Tags wie virtuelle Schubladen verstehen, in denen Dokumente liegen. Sie eignen sich erstklassig, um Dokumenten eine Thematik zuzuweisen, die über viele Korrespondenten und Dokumenttypen verteilt ist (z.B. Kfz) - oder einfach nur als Statusindikator.&lt;/p&gt;
&lt;p&gt;&lt;a href="tagging.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Tagging"
width="1601"
height="1144"
src="/post/2024-02-11-paperless-guide-classification/tagging_hu_da87daf503d45450.webp"
srcset="/post/2024-02-11-paperless-guide-classification/tagging_hu_da87daf503d45450.webp 800w, /post/2024-02-11-paperless-guide-classification/tagging_hu_47101b08c860a699.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-11-paperless-guide-classification/tagging.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Damit es jedoch nicht zu komplex wird, beschränke ich mich auf einige wenige, dafür eindeutige Tags.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Tag&lt;/th&gt;
&lt;th style="text-align: left"&gt;Beschreibung&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Ausgang&lt;/td&gt;
&lt;td style="text-align: left"&gt;Das Dokument ist ein Ausgangsdokument, wurde also von mir initiiert.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Kfz&lt;/td&gt;
&lt;td style="text-align: left"&gt;Verträgen, Rechnungen, etc. verleihe ich mit diesem Tag einen Kfz-Kontext. So kann ich schnell sämtliche Unterlagen zu meinen Autos wiederfinden.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Neu&lt;/td&gt;
&lt;td style="text-align: left"&gt;Hierbei handelt es sich um meinen Posteingangs-Tag. Alle Dokumente mit diesem Tag haben den Status &lt;strong&gt;neu&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Problem&lt;/td&gt;
&lt;td style="text-align: left"&gt;Dieser Tag wird von meiner Middleware verwendet, wenn ich an einem Dokument noch etwas nacharbeiten muss. Darauf gehe ich später detailliert ein.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Steuer&lt;/td&gt;
&lt;td style="text-align: left"&gt;Dokumente mit diesem Tag werden von mir für die nächste Steuererklärung benötigt.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Todo&lt;/td&gt;
&lt;td style="text-align: left"&gt;Das sind Dokumente, mit denen ich zu einem späteren Zeitpunkt noch etwas vorhabe, oder bei denen ich noch auf eine Antwort warte.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Wichtig&lt;/td&gt;
&lt;td style="text-align: left"&gt;Extrem wichtige Dokumente, die ich schnell wiederfinden muss, wenn ich sie brauche.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 class="relative group"&gt;Speicherpfade
&lt;div id="speicherpfade" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#speicherpfade" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Paperless-ngx&lt;/em&gt; bietet noch eine weitere Möglichkeit, Schubladen zu erschaffen. Nicht dass wir davon nicht schon bereits einige hätten &amp;#x1f613;. In diesem Fall handelt es sich um echte Ordner im Dateisystem, in denen die echten PDF-Dateien dann abgelegt werden, die du im DMS abspeicherst. Das ist natürlich ein reines Kosmetik-Feature und bietet Vorteile für Backups, oder wenn man all seine Dokumente bspw. zusätzlich bei einem Cloud-Anbieter speichern möchte.&lt;/p&gt;
&lt;p&gt;&lt;a href="storage-paths.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Speicherpfade"
width="1601"
height="1144"
src="/post/2024-02-11-paperless-guide-classification/storage-paths_hu_45023c24b7a55528.webp"
srcset="/post/2024-02-11-paperless-guide-classification/storage-paths_hu_45023c24b7a55528.webp 800w, /post/2024-02-11-paperless-guide-classification/storage-paths_hu_e94046f5900b7c82.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-11-paperless-guide-classification/storage-paths.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ich nutze zwar die physischen Dateiordner nicht, Speicherpfade stellen für mich allerdings ein zusätzliches Klassifizierungsmerkmal dar. So existiert nicht nur für jedes meiner Autos ein echter Dateiordner mit allen Dokumenten drin, meine Middleware weiß hierdurch sogar, um welches Auto es sich handelt. So spare ich mir für jedes Auto einen eigenen Tag anzulegen, denn viele Speicherpfade sind aus meiner Sicht weniger störend als viele Tags.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Middleware
&lt;div id="middleware" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#middleware" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Ich habe nun mehrmals eine Middleware erwähnt. Hierbei handelt es sich um eine selbst entwickelte Python-App, die wiederkehrende Monitoring-Aufgaben wahrnimmt. Die App baut auf diesem Python Modul auf, welches ich auch entwickelt habe:&lt;/p&gt;
&lt;p&gt;Wenn du ein bisschen mehr darüber erfahren möchtest, solltest du &lt;a href="/post/2024-08-28-paperless-guide-customization/"&gt;hier&lt;/a&gt; weiterlesen &amp;#x1f604;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Erkennungs-Algorithmen
&lt;div id="erkennungs-algorithmen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#erkennungs-algorithmen" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Die Klassifizierung ist der Prozess, bei dem man Dokumenten jeweils Korrespondenten, Dokumenttyp, Tags und ggf. einen Speicherpfad zuweist. Das muss man glücklicherweise nicht jedes Mal komplett per Hand machen, &lt;em&gt;Paperless-ngx&lt;/em&gt; wird mit einigen Erkennungs-Algorithmen ausgeliefert. Darüber kannst du &lt;a href="https://docs.paperless-ngx.com/advanced_usage/#matching" target="_blank" rel="noopener noreferrer"&gt;hier &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; mehr lesen. Falls die automatische Erkennung nicht zum gewünschten Ergebnis führt, kann man natürlich selbst den korrekten Wert einstellen. Im Falle der Auto-Erkennung lernt &lt;em&gt;Paperless-ngx&lt;/em&gt; dann von deiner Entscheidung und macht es mit ein bisschen Glück direkt beim nächsten Mal richtig.&lt;/p&gt;
&lt;p&gt;&lt;a href="matching-algorithms.webp"&gt;&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Bild: Erkennungs-Algorithmen"
width="1601"
height="1144"
src="/post/2024-02-11-paperless-guide-classification/matching-algorithms_hu_ff08f166f8cebced.webp"
srcset="/post/2024-02-11-paperless-guide-classification/matching-algorithms_hu_ff08f166f8cebced.webp 800w, /post/2024-02-11-paperless-guide-classification/matching-algorithms_hu_11d8636fb615a366.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="/post/2024-02-11-paperless-guide-classification/matching-algorithms.webp"&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 class="relative group"&gt;Keine
&lt;div id="keine" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#keine" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Die Verwendung von Erkennungs-Algorithmen wird deaktiviert.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Irgendein Wort, Alle
&lt;div id="irgendein-wort-alle" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#irgendein-wort-alle" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Der Inhalt eines Dokuments wird nach den Wörtern im Zuweisungsmuster durchsucht. Legst du das Zuweisungsmuster auf &lt;code&gt;Rechnung&lt;/code&gt; fest, werden alle Dokumente entsprechend klassifiziert, wenn sie das Wort &lt;em&gt;Rechnung&lt;/em&gt; enthalten.&lt;/p&gt;
&lt;p&gt;Beim Zuweisungsmuster &lt;code&gt;Rechnung Baumarkt Köln&lt;/code&gt; trifft der Erkennungs-Algorithmus &lt;strong&gt;Irgendein Wort&lt;/strong&gt;, sobald eines der drei Wörter im Dokument vorkommt. &lt;strong&gt;Alle&lt;/strong&gt; trifft nur dann, wenn alle Wörter erkannt werden konnten. Du hast richtig erkannt: mehrere Wörter werden einfach durch ein Leerzeichen voneinander getrennt.&lt;/p&gt;
&lt;p&gt;Es ist aber auch möglich, nach Wörtern mit enthaltenen Leerzeichen zu suchen. Das Prinzip ist fast dasselbe wie mit einzelnen Wörtern: &lt;code&gt;Rechnung &amp;quot;Baumarkt Köln&amp;quot;&lt;/code&gt;. &lt;strong&gt;Irgendein Wort&lt;/strong&gt; trifft nur, wenn die Wörter &lt;em&gt;Rechnung&lt;/em&gt; oder (Achtung!) &lt;em&gt;Baumarkt Köln&lt;/em&gt; im Dokument vorkommen. Du kennst das von gängigen Suchmaschinen, denn dort ist es genauso. &lt;strong&gt;Alle&lt;/strong&gt; trifft wieder nur, wenn beide Wörter vorkommen.&lt;/p&gt;
&lt;p&gt;Die Reihenfolge der Wörter im Dokument spielt übrigens keine Rolle, wichtig ist nur, &lt;em&gt;dass&lt;/em&gt; sie vorkommen.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Exakt
&lt;div id="exakt" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#exakt" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Dieser Erkennungs-Algorithmus verhält sich ähnlich wie &lt;strong&gt;Irgendein Wort&lt;/strong&gt; und &lt;strong&gt;Alle&lt;/strong&gt;, nur dass hier nicht im Kontext von Wörtern, sondern Zeichenketten gesucht wird.&lt;/p&gt;
&lt;p&gt;Das Zuweisungsmuster &lt;code&gt;Rechnung Baumarkt Köln&lt;/code&gt; setzt also dann voraus, dass im Dokument auch tatsächlich &lt;em&gt;Rechnung Baumarkt Köln&lt;/em&gt; am Stück ausgeschrieben wurde, damit &lt;strong&gt;Exakt&lt;/strong&gt; treffen kann.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Regulärer Ausdruck (Regex)
&lt;div id="regulärer-ausdruck-regex" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#regul%c3%a4rer-ausdruck-regex" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Liebhaber von regulären Ausdrücken werden auf ihre Kosten kommen, auch ich bin ein großer Freund davon. Aufgrund der Komplexität von Regex empfehle ich die Verwendung allerdings nur, wenn du wirklich weißt, was du da machst. Es gibt leider extrem beschränkte &lt;em&gt;Debugging Funktionen&lt;/em&gt; dafür in &lt;em&gt;Paperless-ngx&lt;/em&gt;, neben der Logdatei gibt es nämlich keine. Im schlimmsten Fall bekommst du niemals mit, dass dein Zuweisungsmuster also gar nicht funktioniert.&lt;/p&gt;
&lt;p&gt;Möchtest du Regex besser kennenlernen, empfiehlt sich die offizielle &lt;a href="https://docs.python.org/3/library/re.html" target="_blank" rel="noopener noreferrer"&gt;Python Dokumentation &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Ungenau (Fuzzy)
&lt;div id="ungenau-fuzzy" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ungenau-fuzzy" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Ich bin mir nicht sicher, was ich hierüber schreiben soll. &lt;em&gt;Fuzzy Match&lt;/em&gt; war bislang niemals die Lösung einer meiner Use-Cases, aber vielleicht underrate ich den Erkennungs-Algorithmus ja auch einfach bodenlos. Ich werde mir vornehmen, mehr damit zu arbeiten und zu sehen, ob und wie er lebensverändernd sein könnte.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Auto
&lt;div id="auto" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#auto" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Paperless-ngx&lt;/em&gt; erlernt die Zuweisung mit der Zeit automatisch. Ich nutze die &lt;strong&gt;Auto-Erkennung&lt;/strong&gt;, wann immer ich bei einem Klassifizierungsmerkmal genügend Dokumente erwarte; ein Model muss schließlich mit genug Daten trainiert werden.&lt;/p&gt;
&lt;p&gt;Die automatische Zuweisung funktionierte bereits mit der Vorgänger-Software recht zuverlässig und ich bin sehr zufrieden damit.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@blocks?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;blocks &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/tilt-shift-objektivfotografie-eines-schwarzen-laptop-computers-TkEPQPWr2sY?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Seit &lt;em&gt;Paperless-ngx&lt;/em&gt; v2.2.0 gibt es logische Dokumentenverknüpfungen, womit sich Dokumente verbinden lassen. Dies hat Stand 02.01.2024 jedoch weder eine Auswirkung auf die Qualität der Suchergebnisse, noch eine Visualisierung im UI.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry><entry><title>Paperless Guide: Setup</title><link href="https://tbsch.de/post/2024-02-04-paperless-guide-setup/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-02-04-paperless-guide-setup/</id><published>2024-02-04T00:00:00Z</published><updated>2024-02-04T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="home-lab"/><category term="docker"/><category term="guide"/><category term="paperless"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-02-04-paperless-guide-setup/featured.webp"/><summary type="html">Zeit für den digitalen Wandel: ein neues papierloses Büro aufsetzen.</summary><content type="html">&lt;p&gt;Viele Wege führen nach Rom, zumindest aber benötigst du eine Komponente: ein Gerät, auf dem Services betrieben werden können. Hier setzt &lt;em&gt;Paperless-ngx&lt;/em&gt; nur wenige Grenzen. Ich habe mich für die virtualisierte Variante mit Docker&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; entschieden, die Docker Bridge läuft auf meinem Synology NAS&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;. Dieser Leitfaden beschränkt sich auf die Verwendung von &lt;strong&gt;Docker&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="info"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Info
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Bitte beachte, dass ein paar Vorkenntnisse notwendig sind. Grundsätzlich ist aber jeder in der Lage, ein papierloses Büro zu betreiben, wenn er sich in die Materie einarbeitet und Englisch beherrscht.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 class="relative group"&gt;Dokumentation
&lt;div id="dokumentation" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dokumentation" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Wichtigste Informationsquelle für die folgenden Inhalte ist die Webseite von &lt;a href="https://docs.paperless-ngx.com" target="_blank" rel="noopener noreferrer"&gt;&lt;em&gt;Paperless-ngx&lt;/em&gt; &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Setup
&lt;div id="setup" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#setup" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Ich empfehle stets die Verwendung von &lt;strong&gt;docker compose&lt;/strong&gt;&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;, da es die Handhabung von Containern enorm erleichtert. Praktischerweise liefern die Macher von &lt;em&gt;Paperless-ngx&lt;/em&gt; bereits diverse Beispiel-Setups mit, welche &lt;a href="https://github.com/paperless-ngx/paperless-ngx/tree/dev/docker/compose" target="_blank" rel="noopener noreferrer"&gt;hier &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; zur Verfügung stehen.&lt;/p&gt;
&lt;p&gt;Meine Installation besteht aus den folgenden Komponenten:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;broker&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;redis:7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;webserver&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;paperlessngx/paperless-ngx:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;gotenberg&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;gotenberg/gotenberg:7.8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;tika&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ghcr.io/paperless-ngx/tika:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Bewusst verzichte ich auf den Einsatz einer relationalen Datenbank, wie z.B. PostgreSQL. Ich möchte mein papierloses Büro einfach nicht von einer Datenbank abhängig machen, denn diese benötigt auch Wartung, Backups, etc. Ein weiterer Vorteil ist, dass sich eine &lt;em&gt;sqlite&lt;/em&gt;-Datei sehr viel einfacher sichern lässt &amp;#x1f60e;. Solltest du eine &lt;em&gt;MySQL&lt;/em&gt;-Datenbank verwenden wollen, gibt es noch weitere Dinge zu &lt;a href="https://docs.paperless-ngx.com/advanced_usage/#mysql-caveats" target="_blank" rel="noopener noreferrer"&gt;beachten &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="warning"&gt;
&lt;div class="flex items-center gap-2 font-semibold text-inherit"&gt;
&lt;div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"&gt;&lt;span class="relative block icon"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path fill="currentColor" d="M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z"/&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="grow"&gt;
Warning
&lt;/div&gt;
&lt;/div&gt;&lt;div class="admonition-content mt-3 text-base leading-relaxed text-inherit"&gt;&lt;p&gt;Wenn du dich mit Datenbanken nicht gut auskennst, rate ich dringend dazu, ebenfalls auf deren Einsatz zu verzichten! Bei falscher Handhabung droht Datenverlust; und genau das muss vermieden werden. Es gibt absolut keinen großen Vorteil durch ihren Einsatz, da &lt;em&gt;Paperless-ngx&lt;/em&gt; keine horrenden Datenmengen speichert. Meine &lt;em&gt;sqlite&lt;/em&gt;-Datenbank ist gerade einmal 14 MB groß (über 3000 Dokumente, Stand 30.12.2023).&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Gotenberg&lt;/strong&gt; und &lt;strong&gt;Tika&lt;/strong&gt; sind optionale Bestandteile der &lt;em&gt;Paperless-ngx&lt;/em&gt;-Installation. Sie werden benötigt, um &lt;em&gt;Office&lt;/em&gt;- und E-Mail-Dateien verarbeiten zu können. Ich nutze diese Services zwar extrem sporadisch, Haben ist aber besser als Brauchen. &lt;a href="https://docs.paperless-ngx.com/configuration/#optional-services" target="_blank" rel="noopener noreferrer"&gt;Hier &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; findest du weitergehende Erläuterungen dazu.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Konfiguration
&lt;div id="konfiguration" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#konfiguration" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Meine &lt;em&gt;docker compose&lt;/em&gt;-Konfiguration ist natürlich auf meine Bedürfnisse zugeschnitten. Hier ein kleiner Einblick in den &lt;em&gt;Paperless-ngx&lt;/em&gt;-Container. Alle Ordner sind frei zugänglich auf dem Dateisystem meines Servers, &lt;em&gt;Docker Volumes&lt;/em&gt; nutze ich nicht:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;./data:/usr/src/paperless/data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;./media:/usr/src/paperless/media&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;./export:/usr/src/paperless/export&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;./consume:/usr/src/paperless/consume&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;./hooks:/usr/src/paperless/scripts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;./trash:/usr/src/paperless/trash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;environment&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_REDIS&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;redis://broker:6379&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_TIKA_ENABLED&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_TIKA_GOTENBERG_ENDPOINT&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;http://gotenberg:3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_TIKA_ENDPOINT&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;http://tika:9998&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_TASK_WORKERS&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_THREADS_PER_WORKER&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_PRE_CONSUME_SCRIPT&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;/usr/src/paperless/scripts/PRE_CONSUME.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_POST_CONSUME_SCRIPT&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;/usr/src/paperless/scripts/POST_CONSUME.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_TRASH_DIR&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;/usr/src/paperless/trash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_URL&lt;/span&gt;: &lt;span style="color:#75715e"&gt;# vertraulich&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_TRUSTED_PROXIES&lt;/span&gt;: &lt;span style="color:#75715e"&gt;# vertraulich&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_USE_X_FORWARD_HOST&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_USE_X_FORWARD_PORT&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_PROXY_SSL_HEADER&lt;/span&gt;: [&lt;span style="color:#e6db74"&gt;&amp;#34;HTTP_X_FORWARDED_PROTO&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;https&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_SECRET_KEY&lt;/span&gt;: &lt;span style="color:#75715e"&gt;# vertraulich&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_ENABLE_UPDATE_CHECK&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_OCR_LANGUAGES&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;deu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_OCR_LANGUAGE&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;deu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_FILENAME_FORMAT&lt;/span&gt;: {&lt;span style="color:#ae81ff"&gt;owner_username}/{created}_{correspondent}_{document_type}_{title}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# QR Code Scanner&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_CONSUMER_ENABLE_BARCODES&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;PAPERLESS_CONSUMER_BARCODE_SCANNER&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ZXING&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Alle Optionen sind detailliert &lt;a href="https://docs.paperless-ngx.com/configuration/#docker" target="_blank" rel="noopener noreferrer"&gt;hier &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; dokumentiert, jedes Detail kann und sollte nachgelesen werden. Für Vorschläge zu meiner Konfiguration bin ich jederzeit zu haben, nimm einfach Kontakt mit mir auf!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Erläuterungen:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wie eingangs erwähnt, behalte ich mir den Zugriff auf alle Daten über das Dateisystem vor. Das erleichtert Backups ungemein.&lt;/li&gt;
&lt;li&gt;Ich verwende Custom Scripts, um Aktionen vor und nach dem Konsumieren von Dokumenten auszuführen.&lt;/li&gt;
&lt;li&gt;Der Papierkorb ist aktiviert. Sollte nicht passieren, aber falls ich mal etwas lösche, ist es nicht sofort verloren.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Paperless-ngx&lt;/em&gt; läuft in meinem Home Lab innerhalb eines &lt;em&gt;Traefik&lt;/em&gt;&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;-Netzwerks, ist also hinter einem Proxy.&lt;/li&gt;
&lt;li&gt;Beim &lt;code&gt;PAPERLESS_FILENAME_FORMAT&lt;/code&gt; wird für jeden Eigentümer ein eigener Ordner angelegt. &lt;em&gt;Paperless-ngx&lt;/em&gt; ist mandantenfähig, ein bisschen &amp;#x1f609;. Für den Privathaushalt mit mehreren Personen reicht es vollkommen.&lt;/li&gt;
&lt;li&gt;Der Barcode-Scanner ist aktiviert. Für eine bessere Erkennung von kleinen QR Codes auf Dokumenten verwende ich &lt;code&gt;ZXING&lt;/code&gt;. Ein anderer Paperless-User, &lt;em&gt;Marvin Gaube&lt;/em&gt;, hat einen interessanten &lt;a href="https://margau.net/posts/2023-04-16-paperless-ngx-asn/" target="_blank" rel="noopener noreferrer"&gt;Artikel &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; darüber verfasst.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Fazit
&lt;div id="fazit" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fazit" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Es gibt viele Details, über die man seine &lt;em&gt;Paperless-ngx&lt;/em&gt;-Installation für den persönlichen Gebrauch optimieren kann. Das hängt immer sehr vom eigenen Use-Case, aber auch der eingesetzten Technik ab.&lt;/p&gt;
&lt;p&gt;Auf die oben angesprochenen Custom Scripts gehe ich im weiteren Verlauf detaillierter ein. Das ist ein extrem mächtiges Tool, womit sich allerhand Schandtaten realisieren lassen &amp;#x1f601;. Stichwort: eigene Regelwerke, Validierung und Nachhalten eben dieser.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@lucabravo?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Luca Bravo &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/apple-macbook-neben-computermaus-auf-tisch-9l_326FISzk?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Containermanager, &lt;a href="https://www.docker.com" target="_blank" rel="noopener noreferrer"&gt;docker.com &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Network Attached Storage, &lt;a href="https://www.synology.com/de-de" target="_blank" rel="noopener noreferrer"&gt;Synology Webseite &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Mehr Infos auf &lt;a href="https://github.com/docker/compose" target="_blank" rel="noopener noreferrer"&gt;docker-compose &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;Traefik ist ein Reverse Proxy, &lt;a href="https://doc.traefik.io/traefik/" target="_blank" rel="noopener noreferrer"&gt;traefik.io &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry><entry><title>Paperless Guide: Einführung</title><link href="https://tbsch.de/post/2024-01-28-paperless-guide-introduction/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-01-28-paperless-guide-introduction/</id><published>2024-01-28T00:00:00Z</published><updated>2024-01-28T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="home-lab"/><category term="docker"/><category term="guide"/><category term="paperless"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-01-28-paperless-guide-introduction/featured.webp"/><summary type="html">Kurzer Abstecher zu den alltäglichen Themen mit der Papier-Ablage.</summary><content type="html">&lt;p&gt;Papierkram. Jeder von uns hat ihn, jeder muss ihn bewältigen, rechtzeitig auf Ereignisse reagieren, Schriftgut ablegen - und irgendwann im Bedarfsfall wiederfinden. Einige haben sich hierfür ein straffes Ordnersystem ausgedacht, andere feuern ihre Dokumente in irgendeine Kiste. Die Ablageregeln, die man sich hierfür aufgestellt hat, geraten mit den Jahren möglicherweise in Vergessenheit und bestimmte Dokumenttypen lagern dann an mehreren Stellen - der Worst Case ist eingetreten.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Lösungsansätze
&lt;div id="lösungsansätze" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#l%c3%b6sungsans%c3%a4tze" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Nacheinander probierte ich verschiedene Lösungsansätze aus und entwickelte so mit der Zeit meine heutige Lösung.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Ablage nach Datum
&lt;div id="ablage-nach-datum" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ablage-nach-datum" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Da ich mich 2016 noch nicht mit privaten DMS&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; auskannte bzw. mir mein Use-Case noch nicht bewusst war, entwickelte ich ein einfacheres Ablagesystem in meinen Ordnern. Hierbei heftete ich jedes Dokument einfach nach Datum ab und beschriftete die Ordner mit Zeiträumen.&lt;/p&gt;
&lt;p&gt;Mann, kam ich mir clever vor &amp;#x1f60e;. Bis der Tag kam, an dem ich einen bestimmten Brief von der Krankenkasse gesucht habe. Natürlich wusste ich nicht mehr, wann genau ich ihn erhalten hatte: ich blätterte also jeden Ordner durch, bis ich den Brief schließlich gefunden hatte.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Erste Gehversuche: ecoDMS
&lt;div id="erste-gehversuche-ecodms" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#erste-gehversuche-ecodms" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Über meinen Freund Ben habe ich von &lt;a href="https://www.ecodms.de/de/" target="_blank" rel="noopener noreferrer"&gt;ecoDMS &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; erfahren. Das DMS besteht aus einem &lt;strong&gt;Server&lt;/strong&gt;, der die Dokumente erkennt, klassifiziert und speichert, sowie einem &lt;strong&gt;Client&lt;/strong&gt;. Über diesen kann man dann Dokumente suchen, mit Metainformationen versehen und einfach damit arbeiten. Cool - da ich einen Server zuhause stehen hatte, passte das wie die Faust aufs Auge und meine Dokumente wären immer verfügbar für mich.&lt;/p&gt;
&lt;p&gt;Man steckt bei &lt;em&gt;ecoDMS&lt;/em&gt; sehr viel Zeit in die Konfiguration, überlegt sich Strukturen, Dokumenttypen, Datenfelder, etc. Außerdem musste man der Erkennungssoftware beibringen, &lt;em&gt;wie&lt;/em&gt; Dokumente klassifiziert werden sollen. Über einen praktischen Editor konnte man Bereiche auf einem Dokument auswählen, in denen bspw. immer eine Kundennummer auftauchte. Wahnsinn &amp;#x1f601;!&lt;/p&gt;
&lt;p&gt;Bis Absender von Dokumenten halt mal ihr Brieflayout ändern. Ich musste leider feststellen, dass das ziemlich oft passiert. Dann begann nämlich jedes Mal das große Herumgefummel und &lt;em&gt;ecoDMS&lt;/em&gt; wurde für mich einfach nur noch lästig und fühlte sich so &lt;strong&gt;gar nicht smart&lt;/strong&gt; an. Der lästige Windows-FAT-Client und die schlechten Mobile- und Web-Zugriffsmöglichkeiten rundeten das negative Erlebnis ab.&lt;/p&gt;
&lt;h3 class="relative group"&gt;Die Lösung: Paperless-ngx
&lt;div id="die-lösung-paperless-ngx" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#die-l%c3%b6sung-paperless-ngx" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h3&gt;
&lt;p&gt;Anfang 2021 dann der große, medienwirksame Newcomer: &lt;a href="https://github.com/jonaswinkler/paperless-ng" target="_blank" rel="noopener noreferrer"&gt;paperless-ng &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; - Open Source, ausführbar in vielen privaten Umgebungen, rein webbasierter Zugriff, alles über REST API.&lt;/p&gt;
&lt;p&gt;Als im August 2021 das &lt;strong&gt;Aus&lt;/strong&gt; von &lt;em&gt;paperless-ng&lt;/em&gt; verkündet wurde, machte sich bei mir Enttäuschung breit. Ich hatte schließlich mein &lt;em&gt;ecoDMS&lt;/em&gt; damit abgelöst. Im März 2022 dann die Kehrtwende: ich war offensichtlich nicht der einzige Fan von &lt;em&gt;paperless-ng&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Das Projekt wurde geforkt und ging an den Start als: &lt;strong&gt;&lt;a href="https://github.com/paperless-ngx/paperless-ngx" target="_blank" rel="noopener noreferrer"&gt;Paperless-ngx &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Jeder hat seine Präferenzen, ich favorisiere ganz klar den digitalen Weg: wenig bis gar kein Papier im Aktenschrank. Das passt einfach zu meinem Lifestyle. Auf den folgenden Seiten gehe ich näher auf meine Vorgehensweise mit &lt;em&gt;Paperless-ngx&lt;/em&gt; ein, die sich komplett mühelos in den Alltag integrieren lässt.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@carlheyerdahl?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Carl Heyerdahl &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/silberner-imac-mit-tastatur-und-trackpad-im-zimmer-KE0nC8-58MQ?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Document Management System, &lt;a href="https://de.wikipedia.org/wiki/Dokumentenmanagement" target="_blank" rel="noopener noreferrer"&gt;Wikipedia &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry><entry><title>Meine neue Webseite</title><link href="https://tbsch.de/post/2024-01-01-meine-neue-webseite/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2024-01-01-meine-neue-webseite/</id><published>2024-01-01T00:00:00Z</published><updated>2024-01-01T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="news"/><category term="cloudflare"/><category term="webseite"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2024-01-01-meine-neue-webseite/featured.webp"/><summary type="html">Alles neu, außer der Inhalt. Auf Ruby folgt nun Go: statisch bleibt&amp;rsquo;s.</summary><content type="html">&lt;blockquote&gt;&lt;p&gt;Alles neu, außer der Inhalt. Auf Ruby folgt nun Go: statisch bleibt&amp;rsquo;s.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Ich habe mich dazu entschlossen, meine Webseite neu aufzubauen und auf Cloudflare Pages zu hosten. Bislang habe ich das in meiner heimischen Infrastruktur selbst getan, aufgrund zunehmender Cyberangriffe kommt das aber nicht mehr für mich in Frage.&lt;/p&gt;
&lt;p&gt;Zwischenzeitlich habe ich mit einem VPS experimentiert, aber auch hier muss man natürlich laufend dran bleiben, um Sicherheitsrisiken im Keim zu ersticken. Das ist für mich auf Dauer leider keine Option, da die Webseite einfach nur ein kleines Projekt für nebenbei ist und im Alltag vermutlich häufig viel zu kurz kommt.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Komponenten
&lt;div id="komponenten" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#komponenten" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Programmiersprache: Go&lt;/li&gt;
&lt;li&gt;Static Site Generator: &lt;a href="https://gohugo.io" target="_blank" rel="noopener noreferrer"&gt;Hugo &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Theme: &lt;a href="https://blowfish.page" target="_blank" rel="noopener noreferrer"&gt;Blowfish &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Keine Datenbank&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/tb1337/" target="_blank" rel="noopener noreferrer"&gt;Mein Profil &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cloudflare Pages&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Jekyll? Hugo?
&lt;div id="jekyll-hugo" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#jekyll-hugo" aria-label="Anker"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Ich habe mich vorher an einem Projekt mit &lt;a href="https://jekyllrb.com" target="_blank" rel="noopener noreferrer"&gt;Jekyll &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; versucht, soweit hat das auch wunderbar funktioniert. Das Geflecht aus Ruby-Abhängigkeiten hat mir jedoch einfach nicht so gut gefallen, es verursachte immer wieder Probleme beim Build der Webseite. Als Anwender möchte ich mich aber einfach nicht mit solchen elementaren Herausforderungen herumplagen müssen und erwarte, dass Dinge einfach funktionieren. Also habe ich mich in letzter Konsequenz von Jekyll und dem &lt;a href="https://github.com/mmistakes/minimal-mistakes" target="_blank" rel="noopener noreferrer"&gt;Minimal Mistakes Theme &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; wieder getrennt. So einfach ist das.&lt;/p&gt;
&lt;p&gt;Die Tatsache, eine Webseite einfach mit Markdown runterschreiben zu können, hat mir bei Jekyll jedoch so gut gefallen, dass ich nun bei Hugo gelandet bin. Wollen wir hoffen, dass es nun dabei bleibt &amp;#x1f601;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@freiburgermax?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Max Langelott &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/silhouette-von-kranwagen-d3_cFMe97Ec?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>pypaperless v2 erschienen</title><link href="https://tbsch.de/post/2023-12-19-pypaperless-v2-erschienen/" rel="alternate" type="text/html"/><id>https://tbsch.de/post/2023-12-19-pypaperless-v2-erschienen/</id><published>2023-12-19T00:00:00Z</published><updated>2023-12-19T00:00:00Z</updated><author><name>Tobias Schulz</name></author><category term="news"/><category term="paperless"/><category term="projekt"/><category term="python"/><link rel="enclosure" type="image/webp" href="https://tbsch.de/post/2023-12-19-pypaperless-v2-erschienen/featured.webp"/><summary type="html">Ich habe pypaperless v2 veröffentlicht.</summary><content type="html">&lt;p&gt;Seit April 2022 gibt es nun schon &lt;em&gt;pypaperless&lt;/em&gt;, also den kleinen API Client für Paperless-ngx. Zugegeben, ich habe dem Projekt nie wirklich viel Liebe zukommen lassen, da ich mich zu der Zeit auch noch gar nicht viel mit Python beschäftigt habe. Das Ergebnis war ein kleines Python-Modul mit wahrlich keinem guten Code.&lt;/p&gt;
&lt;p&gt;Ich habe mir jedoch in den Kopf gesetzt, &lt;a href="https://docs.paperless-ngx.com" target="_blank" rel="noopener noreferrer"&gt;Paperless-ngx &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; als Integration nach &lt;a href="https://www.home-assistant.io" target="_blank" rel="noopener noreferrer"&gt;Home Assistant &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; zu bringen. Um diesem Ziel einen Schritt näher zu kommen, war ein Refactoring des kompletten Codes von &lt;em&gt;pypaperless&lt;/em&gt; notwendig: Es musste in einem &lt;code&gt;async&lt;/code&gt; Umfeld funktionieren.&lt;/p&gt;
&lt;p&gt;Heute war es nach langer Arbeit dann endlich so weit: Version 2 konnte an den Start gehen &amp;#x1f601;!&lt;/p&gt;
&lt;p&gt;Viel Spaß mit &lt;em&gt;pypaperless&lt;/em&gt; v2!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Das Titel-/Hintergrundbild stammt von &lt;a href="https://unsplash.com/de/@cdr6934?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Chris Ried &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/ein-computerbildschirm-mit-einem-haufen-code-darauf-ieic5Tq8YMk?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" target="_blank" rel="noopener noreferrer"&gt;Unsplash &lt;i class="ti ti-external-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;</content></entry></feed>