Zur Fensterüberwachung nutze ich die Kontaktsensoren von Aqara im versteckten Einbau am Fenster (mehr dazu).
Das erwartet dich in diesem Artikel
Neuen Datenpunkt erstellen
Zunächst legst du dir einen eigenen Datenpunkt der Art „Zahl“ an. Als Name nimmst du zum Beispiel „Fenster offen“:
Sensoren einer Aufzählung zuweisen
Um später nur auf Änderungen deiner Fenster oder Türen zu triggern, solltest du den State jedes Sensors, den du überwachen willst, einer „Funktion“ hinzufügen, zum Beispiel „Fenster“. Lege dazu unter „Aufzählungen“ eine neue Funktion an:
Danach wechselst du in „Objekte“ und wählst deinen Kontaktsensor aus. Dem State, der den „geöffnet“-Zustand überwacht, weist du die Funktion „Fenster“ zu:
Blockly-Script erstellen
Dann erstellst du ein neues Blockly-Script und fügst einen „falls“-Trigger ein. Als Auslöser wählst du „IDs vom Selektor“ (in diesem Artikel erfährst du mehr über diesen Selektor):
state[id=*](functions=fenster)
Dadurch reagiert das Script auf alle Änderungen innerhalb der Aufzählung bzw. Funktion „Fenster“.
Als nächstes erstellst du im Bereich „Variablen“ eine neue Variable „x“ und ziehst den Block „setze auf“ aus dem Bereich „Variablen“ in den Trigger. An den Eingang setzt du die Zahl „0“ aus dem Mathematik „Bereich“:
Dann fügst du aus dem Bereich „Schleifen“ eine neuen „für jeden Wert aus Liste“-Block ein. An den Eingang hängst du ebenfalls einen „IDs vom Selektor“ mit dem gleichen Inhalt wie eben (mehr zum Thema „automatische Listen“ erfährst du hier):
Als Nächstes fügst du einen Logik-Block „falls mache“ in die Schleife ein. Als Bedingung hängst du einen „Wert von Objekt“ aus dem Bereich „System“ an und weißt ihm die Variable „i“ (aus der Schleife) zu. Damit löst die Bedingung „mache“ aus, wenn der Wert von „i“ wahr ist:
Nun setzt du in den „falls mache“-Block einen „erhöhe um“-Block aus dem Bereich „Variablen“ ein. An den Eingang setzt du die Zahl „1“ aus dem Mathematik „Bereich“:
Jetzt fehlt nur noch der Befehl, die ermittelte Zahl in deinen Datenpunkt zu schreiben. Dafür benötigst du den „steuere mit“-Block aus dem Bereich „System“. Wähle den oben erstellten Datenpunkt („Fenster offen“) aus. In das leere Feld „mit“ setzt du die Variable „x“ ein:
Der Trigger löst nun bei jedem Öffnen und Schließen deiner Fenster aus und durchläuft eine Schleife, in dem der Status jedes Sensors (der Aufzählung „Fenster“) abgefragt wird. Du kannst das Script also auch bei geöffneten Fenstern starten und erhältst einen validen Wert.
Du kannst dieser Aufzählung jederzeit weitere Datenpunkte/Geräte hinzufügen, ohne das Script anpassen zu müssen.
Hinweis: Nach dem ersten Start des Scripts ist es notwendig, dass du eins deiner Fenster testweise öffnest/schließt, damit die Script-Logik initiiert wird und alle Fenster-Zustände ausgewertet werden.
Fertiges Script
Blockly
<xml xmlns="https://developers.google.com/blockly/xml">
<variables>
<variable id="(hHr_ae4nAyqkCl/QX*w">x</variable>
<variable id="9sl@{VQ/amrd~ZTB}e/O">i</variable>
</variables>
<block type="comment" id="bP#C[SIFZAwjrGNLRvfJ" x="-288" y="-812">
<field name="COMMENT">Offene Fenster zählen</field>
<next>
<block type="on_ext" id="RT3@Kxqxg#w3f=(kzwCu">
<mutation xmlns="http://www.w3.org/1999/xhtml" items="1"></mutation>
<field name="CONDITION">ne</field>
<field name="ACK_CONDITION"></field>
<value name="OID0">
<shadow type="field_oid" id="0)0sp$I1ccfm%4Sde-mT">
<field name="oid">default</field>
</shadow>
<block type="selector" id=",lvP%A]1J?Mf^@0s2D%[">
<field name="TEXT">state[id=*](functions=fenster)</field>
</block>
</value>
<statement name="STATEMENT">
<block type="variables_set" id=":2U;X]t,z4J/+D;%yb~b">
<field name="VAR" id="(hHr_ae4nAyqkCl/QX*w">x</field>
<value name="VALUE">
<block type="math_number" id="B}eHQ9lDdZMCn@UJ*jG8">
<field name="NUM">0</field>
</block>
</value>
<next>
<block type="controls_forEach" id="~PaFX`X@5n{TM9K^{Jw6">
<field name="VAR" id="9sl@{VQ/amrd~ZTB}e/O">i</field>
<value name="LIST">
<block type="selector" id="xQ^Q5{h5V@5PLI+YO@i.">
<field name="TEXT">state[id=*open](functions=fenster)</field>
</block>
</value>
<statement name="DO">
<block type="controls_if" id="-3J;6~}7Ac!D}IR`/Dr1">
<value name="IF0">
<block type="get_value_var" id=")kSAuROX6lA-U2N,FJ1Q">
<field name="ATTR">val</field>
<value name="OID">
<shadow type="text">
<field name="TEXT"></field>
</shadow>
<block type="variables_get" id="!fALmmY3PSF+?rGHUXQ,">
<field name="VAR" id="9sl@{VQ/amrd~ZTB}e/O">i</field>
</block>
</value>
</block>
</value>
<statement name="DO0">
<block type="math_change" id="8cRG{Bp7_Q*vW0eisWuM">
<field name="VAR" id="(hHr_ae4nAyqkCl/QX*w">x</field>
<value name="DELTA">
<shadow type="math_number" id="qgm5bBhk_!IL{kHE51bJ">
<field name="NUM">1</field>
</shadow>
</value>
</block>
</statement>
</block>
</statement>
<next>
<block type="control" id=".:1)R,@*mq_#zuTK(H4E">
<mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
<field name="OID">Eigene.0.Fenster_Markise.Fenster_offen</field>
<field name="WITH_DELAY">FALSE</field>
<value name="VALUE">
<block type="variables_get" id="xkO0oZvoGwB3u_2u#+n]">
<field name="VAR" id="(hHr_ae4nAyqkCl/QX*w">x</field>
</block>
</value>
</block>
</next>
</block>
</next>
</block>
</statement>
</block>
</next>
</block>
</xml>
Javascript
var x, i;
// Offene Fenster zählen
on({id: Array.prototype.slice.apply($("state[id=*](functions=fenster)")), change: "ne"}, async function (obj) {
var value = obj.state.val;
var oldValue = obj.oldState.val;
x = 0;
var i_list = Array.prototype.slice.apply($("state[id=*](functions=fenster)"));
for (var i_index in i_list) {
i = i_list[i_index];
if (getState(i).val) {
x = (typeof x == 'number' ? x : 0) + 1;
}
}
setState("Eigene.0.Fenster_Markise.Fenster_offen"/*Fenster_Markise.Fenster_offen*/, x);
});
21 Kommentare
Kommentieren[…] Offene Fenster zählen mit Blockly […]
Wenn ich das richtig sehe, müssen bei diesem Script dann aber alle Fenster geschlossen sein wenn es startet, oder? Das ist doch auch nicht so toll.
Wäre ein count() nicht wesentlich besser?
Ja, das stimmt. Ich werde das Script nochmal abändern, so dass es unabhängig von geöffneten Fenstern gestartet werden kann und diese dann auch sauber anzeigt. Danke für den Hinweis! Viele Grüße
Hallo,
leider ist der der letzt und vorletzte Screenshot vor dem finalen/fertigen Script nicht lesbar. Könntest Du die bitte nachpflegen, ich möchte Dein Blockly Script gerne verwenden und adaptieren.
Grüsse
Reiner
Hallo Reiner, alle Screenshots sind auffindbar und werden angezeigt. Hast du eventuell mal mit einem anderen Browser getestet? Grüße
Hallo.Läuft bei mir nicht wirklich, der angelegte Datenpunkt erhöht sich nicht.
Benutze HM Fenstersensoren und habe diese in den Auzählungen Fenster eingefügt. Der state hat den Wert „Open(1)“ bei geöffnetem Fenster. Blockly ist auch so wie oben erstellt… Hast du eine Idee? MfG
Setzt den ID-Trugger mal so „ state[id=*](functions=fenster)“
[state.id=*STATE](functions=fenster) war das Zauberwort 🙂
Erstmal vielen Dank an Max für das script! Es lief und lief nie, egal was ich gemacht habe. Bis ich auf Micha’s Kommentar gestossen bin. Ich habe im Trigger Block oben: state[id=*](functions=fenster) und in der Schleife weiter unten : state[id=*STATE](functions=fenster) und damit ging es endlich nach gefühlten 100 Versuchen. Ich nutze ausschließlich Homematic IP Fensterkontakte (HmIP-SWDO-2).
Hallo,
erstmal großes Lob für das tolle Skript. Ich habe verschiedene Fensterkontakte im Einsatz (Homematic, Homematic IP, MAX über CuxD).
Es werden im Skript alle Kontakte erkannt, aber bei einer Änderung wird nichts in den Datenpunkt geschrieben und dieser bleibt bei 0.
Woran kann das liegen?
Danke für deine Antwort.
Gruß Ronny
Hallo Ronny, schick mir mal bitte Screenshots per Mail: von deinem Script und dem Log, nachdem du das Script gestartet hast. Danke!
Hallo Max,
tolle Idee und Erklärung. Vielen Dank dafür. Klappt auch super.
Ich wollte jetzt einbauen, dass ich nach 60 Minuten ne Pushover Mitteilung bekommen sofern ein oder mehrere Fenster noch offen sind. Allerdings will ich nur eine bekommen und nicht für jedes Fenster eine eigene.
Hast du nen Tip?
Lieben Dank
Hallo Jakob, du könntest mit einem neuen Trigger abfragen, ob „falls Wert = 1“ ist (mindestens 1 Fenster geöffnet) und das timeout dann starten. Bei falls = 0 beendest du das timeout wieder. Somit bekommst du die Meldung nur 1 Mal.
Hallo Max,
danke für dieses super Script, funktioniert auf Anhieb wunderbar.
Ich verzweifle aber irgendwie an dem Versuch, zusätzlich zur Anzahl auch den Raumnamen mit zu schreiben. Habe dafür selbstverständlich auch einen entsprechenden Datenpunkt angelegt und die open/close Datenpunkte entsprechenden Räumen zugeordnet. Außerdem habe ich mit Funktionen aus anderen Tutorials von dir experimentiert.
Kannst du mir da ein Tipp geben, wie das funktioniert?
Vielen lieben Dank schon mal!
Hallo Matthias, probier mal das: https://www.machs-smart.de/offene-und-geschlossene-fenster-mit-blockly-als-liste-ausgeben/
Hallo Max,
ich bräuchte hier auch mal Unterstützung…
Hänge am ähnlichen Problem wie mein Vorschreiber weiter oben – Habe HmIP Geräte und er erkennt nur was, wenn ich ID=* mache – aber das bringt mir ja nichts bei den States OPEN(1) oder Closed(0).
Und die Variable am ende mit x bzw im Endeffekt dann „OpenWindows“ wird auch nicht geschrieben.
Verstehe gerade nicht, wo ich den Denkfehler habe..
Hi Daniel,
Hast du deinen Fehler gefunden?
Hänge zur Zeit an der selben Stelle.
MfG Nils
Danke für das Script, ich nutze es bei Homematic IP. Es geht, wenn man die Geräte vorher einem alias zuordnet und den alias in die Auflistung packt. So habe ich es jetzt gelöst.
Danke für die Anleitung. Ich habe als blutiger Anfänger leider ein Problem. Beim Objekt habe ich nur die Typen Name, Zustandstyp und Rolle. Und bei Rolle kann ich „Zahl“ nicht eintragen. Da gibt es eine Liste ohne „Zahl“.
Hallöchen, wie kann ich denn noch die Namen der Sensoren ermitteln die als offen gezählt werden?
Gruß Michael
Hallo Max,
ich nutze Dein Skript auch. Leider erzeugt es einen Fehler den ich nicht nachvollziehen kann. Im Protokoll des ioBroker erscheint immer wieder „TypeError: Liste_komplett.join is not a function“. Hast Du eine Idee?
Danke und Gruß,
Heiner