ioBroker: Offene Fenster zählen

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.

Zur Fensterüberwachung nutze ich die Kontaktsensoren von Aqara im versteckten Einbau am Fenster (mehr dazu).

Neuen Datenpunkt erstellen

Zunächst legst du dir einen eigenen Datenpunkt der Art „Zahl“ an. Als Name nimmst du zum Beispiel „Fenster offen“:

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.

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:

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.

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:

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.

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):

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.
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“:

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.

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):

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.

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:

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.

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“:

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.

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:

Mit einem einfachen Blockly-Script und einem eigenen Datenpunkt kannst du dir die Gesamtzahl geöffneter Fenster oder Türen anzeigen lassen.

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);
});
War dieser Beitrag hilfreich?
Hat dir der Beitrag geholfen?
Die mit Sternchen (*) gekennzeichneten Links sind sogenannte Affiliate-Links. Wenn du auf so einen Affiliate-Link klickst und über diesen Link einkaufst, bekomme ich von dem betreffenden Online-Shop oder Anbieter eine Provision. Für dich verändert sich der Preis nicht.

21 Kommentare

Kommentieren

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

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 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..

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“.

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

Schreibe einen Kommentar