iobroker: Alle Geräte einer Aufzählung auf einmal steuern

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Einstellungen im Javscript-Adapter

Damit das Script wie gewünscht nach dieser Anleitung funktioniert, musst du zuerst in den Instanz-Einstellungen des Javascript-Adapters die Einstellung “Erlaube das Kommando setObject” aktivieren:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Sensoren einer Aufzählung zuweisen

Um später den richtigen Datenpunkt deiner Geräte anzusteuern, solltest du den State jedes Geräts einer „Funktion“ hinzufügen, zum Beispiel „schalten“. Lege dazu unter „Aufzählungen“ eine neue Funktion an:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Danach wechselst du in „Objekte“ und wählst das erste Gerät, dass du schalten möchtest, aus. In diesem Beispiel steuerst du alle Steckdosen an. Daher weist du dem Datenpunkt “on” die Funktion „schalten“ zu:

iobroker: Alle Geräte einer Aufzählung auf einmal steuern

Diesen Vorgang wiederholst du mit allen weiteren Geräten, die du über das Script ansteuern möchtest. Beachte, dass alle Datenpunkte dieser Geräte den gleichen Wert zum Schalten besitzen müssen, also zum Beispiel “true” und “false”. Wenn du Geräte mit unterschiedlichen States ansteuern möchtest, lies bitte weiter unten.

Blockly-Script aufbauen

Als Nächstes baust du dir folgendes Blockly-Script auf. Füge aus dem Bereich „Schleifen“ eine neuen „für jeden Wert aus Liste“-Block ein. An den Eingang hängst du einen „IDs vom Selektor“-Block aus dem Bereich “System mit folgendem Inhalt (mehr zum Thema „IDs vom Selektor“ erfährst du hier):

state[id=*](functions=schalten)
Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Variante 1: Schalten mit Javascript-Funktion

Das Script ruft nun in einer Schleife alle Datenpunkte, deren die Funktion “schalten” zugewiesen ist, ab. Damit das Script diese auch schaltet, benötigst du eine neue “Javascript”-Funktion aus dem Bereich “Funktionen”:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Ziehe dir die Funktion in deinen Blockly-Bereich und füge über das blaue Zahnrad zwei Variablen dazu, die du wie oben abgebildet “zustand” und “device” nennst. Die Funktion selbst nennst du einfach “schalten”:

iobroker: Alle Geräte einer Aufzählung auf einmal steuern

Über die 3 Punkte „…“ öffnest du den Funktions-Editor. In diesen fügst du folgenden Code ein:

setState(device, zustand);

Anschließend speicherst du die Funktion und schließt den Editor. Klicke dann mit der rechten Maustaste auf die Funktion und wähle “Erzeuge ‘Aufruf schalten'”:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Den erzeugen Block ziehst du in deine grüne Schleife. Stecke dann an den Eingang “device” das “i” aus der Schleife (entweder über Rechtsklick auf die Schleife “Erzeuge ‘Lese i'” oder über den Bereich “Variablen”). An den Eingang “zustand” steckst du den “wahr”-Block aus dem Bereich “Logik”:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Je nach dem, wie du die Geräte steuern möchtest, stellst du den Mathematik-Block auf “wahr” (“true”) oder “falsch” (“false”).

Damit das Script nach dem Start nur Geräte steuert, die nicht schon den Wert haben, den du schalten möchtest, brauchst du eine Logik-Abfrage. Baue also um diesen “schreiben mit”-Aufruf einen Logik-Block “falls mache” und stecke an den Eingang einen “=”-Vergleich, den du auf “≠” stellst:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

In das erste Feld vom Vergleich fügst du aus dem Bereich “Syetem” einen “Wert von Objekt ID” mit dem grünen Attribut-Feld:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Stecke dann in das Attribut-Feld das “i” aus der Schleife (entweder über Rechtsklick auf die Schleife “Erzeuge ‘Lese i'” oder über den Bereich “Variablen”) und als zweiten Vergleichswert fügst du den “wahr”-Block aus dem Bereich “Logik” ein. Stelle diesen auf den gleichen Wert wie den vom Logik-Block am Eingang “zustand”:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Ist der Wert des Geräts also ungleich <false> wird er durch das Script auf <false> gesetzt. Ist er schon auf <false>, passiert nichts. Möchtest du die Geräte einschalten, stellst du im Vergleich den Block auf “wahr” und am Eingang “zustand” auf “wahr”.

Wenn du das Script nun manuell, über einen Button in deiner Visualisierung oder ein anderes Script startest, werden alle Geräte der Aufzählung “schalten” gesteuert.

Du kannst dieser Aufzählung jederzeit weitere Datenpunkte hinzufügen, ohne das Script anpassen zu müssen.

Geräte mit underschiedlichen States steuern

Solltest du Geräte mit unterschiedlichen Datenpunkten steuern wollen, darfst du die Funktion “schalten” NICHT dem Datenpunkt zuweisen, sondern dem übergeordneten Gerät. Danach kannst du mit dem “IDs vom Selektor”-Block gezielt auf die einzelen States zugreifen und diese steuern (mehr zum Thema „IDs vom Selektor“ erfährst du hier):

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Fertiges Script

Blockly
<xml xmlns="https://developers.google.com/blockly/xml">
  <variables>
    <variable id="eS!L3|7E$+[`m0M+Yl.%">zustand</variable>
    <variable id="t}+]T(vUwfak5UbTg?Zi">device</variable>
    <variable id="xUX]g|q4Lt:~sYj;);g}">i</variable>
  </variables>
  <block type="procedures_defcustomnoreturn" id="_22s5]gRFyvsP-_]Hlzl" x="13" y="-212">
    <mutation statements="false">
      <arg name="zustand" varid="eS!L3|7E$+[`m0M+Yl.%"></arg>
      <arg name="device" varid="t}+]T(vUwfak5UbTg?Zi"></arg>
    </mutation>
    <field name="NAME">schalten</field>
    <field name="SCRIPT">c2V0U3RhdGUoZGV2aWNlLCB6dXN0YW5kKTs=</field>
    <comment pinned="false" h="80" w="160">Beschreibe diese Funktion …</comment>
  </block>
  <block type="controls_forEach" id="+[t/(d.07toVu:~W6^di" x="13" y="-187">
    <field name="VAR" id="xUX]g|q4Lt:~sYj;);g}">i</field>
    <value name="LIST">
      <block type="selector" id="kQNm?FZg_7qq67_CJyc_">
        <field name="TEXT">state[id=*](functions=schalten)</field>
      </block>
    </value>
    <statement name="DO">
      <block type="controls_if" id="eVl;(jQsbZ)AClAGcK6)">
        <value name="IF0">
          <block type="logic_compare" id="j3u?d:FVW{*Bb9DDMqUW">
            <field name="OP">NEQ</field>
            <value name="A">
              <block type="get_value_var" id="Em7n7Zc(?ooT17~s)bel">
                <field name="ATTR">val</field>
                <value name="OID">
                  <shadow type="text" id="(#`!*29fT-s5VYVh6`su">
                    <field name="TEXT"></field>
                  </shadow>
                  <block type="variables_get" id="H%fpy8XeiSWP~tc0870G">
                    <field name="VAR" id="xUX]g|q4Lt:~sYj;);g}">i</field>
                  </block>
                </value>
              </block>
            </value>
            <value name="B">
              <block type="logic_boolean" id="pewE2Gog3rH4#UPtK4n[">
                <field name="BOOL">FALSE</field>
              </block>
            </value>
          </block>
        </value>
        <statement name="DO0">
          <block type="procedures_callcustomnoreturn" id="Muw4CQ_rkX?,pDC/q?WZ">
            <mutation name="schalten">
              <arg name="zustand"></arg>
              <arg name="device"></arg>
            </mutation>
            <value name="ARG0">
              <block type="logic_boolean" id=")CoqgG.G!g;b9ro~],3T">
                <field name="BOOL">FALSE</field>
              </block>
            </value>
            <value name="ARG1">
              <block type="variables_get" id="s#J![BoyQ5z#KqE[pP-:">
                <field name="VAR" id="xUX]g|q4Lt:~sYj;);g}">i</field>
              </block>
            </value>
          </block>
        </statement>
      </block>
    </statement>
  </block>
</xml>
Javascript
let zustand, device, i;

function schalten(zustand, device) {
    setState(device, zustand);
}

let i_list = Array.prototype.slice.apply($("state[id=*](functions=schalten)"));
for (var i_index in i_list) {
  i = i_list[i_index];
  if (getState(i).val != false) {
    schalten(false, i);
  }
}

Variante 2: Schalten mit “schreibe”-Block

Das Script ruft nun in einer Schleife alle Datenpunkte, deren die Funktion “schalten” zugewiesen ist, ab. Damit nach dem Start nur Geräte gesteuert werden, die nicht schon den Wert haben, den du schalten möchtest, brauchst du eine Logik-Abfrage. Ziehe dir also einen Logik-Block “falls mache” ein die Schleife und stecke an den Eingang einen “=”-Vergleich, den du auf “≠” stellst:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

In das erste Feld vom Vergleich fügst du aus dem Bereich “Syetem” einen “Wert von Objekt ID” mit dem grünen Attribut-Feld:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Stecke dann in das Attribut-Feld das “i” aus der Schleife (entweder über Rechtsklick auf die Schleife “Erzeuge ‘Lese i'” oder über den Bereich “Variablen”) und als zweiten Vergleichswert fügst du den “wahr”-Block aus dem Bereich “Logik” ein. Stelle diesen auf den Wert, auf den deine Geräte umgeschaltet werden sollen:

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Damit das Script auch schaltet, benötigst du einen “schreibe”-Block aus dem Bereich “System. An den Eingang “Objekt ID” steckst du das “i” aus der Schleife und an den Eingang “Wert” den gleichen Logik-Block von eben (mit dem gleichen Wert):

Ich zeige dir in diesem Artikel, wie du alle Geräte einer Aufzählung auf einmal steuern kannst. Diese Anleitung lässt sich auf alle Datenpunkte anwenden, wie beispielsweise Steckdosen, Lichter, Aktoren, Steuerungen usw.

Ist der Wert des Geräts also ungleich <false> wird er durch das Script auf <false> gesetzt. Ist er schon auf <false>, passiert nichts. Möchtest du die Geräte einschalten, stellst du im Vergleich den Block auf “wahr” und am Eingang “zustand” auf “wahr”.

Wenn du das Script nun manuell, über einen Button in deiner Visualisierung oder ein anderes Script startest, werden alle Geräte der Aufzählung “schalten” gesteuert.

Du kannst dieser Aufzählung jederzeit weitere Datenpunkte hinzufügen, ohne das Script anpassen zu müssen.

Fertiges Script

Blockly
<xml xmlns="https://developers.google.com/blockly/xml">
  <variables>
    <variable id="xUX]g|q4Lt:~sYj;);g}">i</variable>
  </variables>
  <block type="controls_forEach" id="+[t/(d.07toVu:~W6^di" x="38" y="-237">
    <field name="VAR" id="xUX]g|q4Lt:~sYj;);g}">i</field>
    <value name="LIST">
      <block type="selector" id="kQNm?FZg_7qq67_CJyc_">
        <field name="TEXT">state[id=*](functions=schalten)</field>
      </block>
    </value>
    <statement name="DO">
      <block type="controls_if" id="eVl;(jQsbZ)AClAGcK6)">
        <value name="IF0">
          <block type="logic_compare" id="j3u?d:FVW{*Bb9DDMqUW">
            <field name="OP">NEQ</field>
            <value name="A">
              <block type="get_value_var" id="ZQ^uSAAgY|yUqwTdN2#!">
                <field name="ATTR">val</field>
                <value name="OID">
                  <shadow type="text" id="fn4xEEO@`^xSp_n@c8+,">
                    <field name="TEXT"></field>
                  </shadow>
                  <block type="variables_get" id="yRp-]{39)wm95E,(I[cs">
                    <field name="VAR" id="xUX]g|q4Lt:~sYj;);g}">i</field>
                  </block>
                </value>
              </block>
            </value>
            <value name="B">
              <block type="logic_boolean" id="pewE2Gog3rH4#UPtK4n[">
                <field name="BOOL">FALSE</field>
              </block>
            </value>
          </block>
        </value>
        <statement name="DO0">
          <block type="control_ex" id="/W)abx4/`Fu8;sLNvL(e">
            <field name="TYPE">false</field>
            <field name="CLEAR_RUNNING">FALSE</field>
            <value name="OID">
              <shadow type="field_oid" id="5*z=;fipNpO^r5G036kg">
                <field name="oid">Object ID</field>
              </shadow>
              <block type="variables_get" id="H%fpy8XeiSWP~tc0870G">
                <field name="VAR" id="xUX]g|q4Lt:~sYj;);g}">i</field>
              </block>
            </value>
            <value name="VALUE">
              <shadow type="logic_boolean" id="%T.g5e|]e(%z/X$6+.WD">
                <field name="BOOL">TRUE</field>
              </shadow>
              <block type="logic_boolean" id=")CoqgG.G!g;b9ro~],3T">
                <field name="BOOL">FALSE</field>
              </block>
            </value>
            <value name="DELAY_MS">
              <shadow type="math_number" id=",,)+03KIu:i!i+wD-*8L">
                <field name="NUM">0</field>
              </shadow>
            </value>
          </block>
        </statement>
      </block>
    </statement>
  </block>
</xml>
Javascript
let i;

let i_list = Array.prototype.slice.apply($("state[id=*](functions=schalten)"));
for (var i_index in i_list) {
  i = i_list[i_index];
  if (getState(i).val != false) {
    setStateDelayed(i, false, false, parseInt(0, 10), false);
  }
}
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.

15 Kommentare

Kommentieren

Hallo,

das sieht sehr stimmig für mich aus, scheitere aber leider schon beim Zuweisen der Funktion an einem Datenobjekt. Die neu erstellte Funktion aus den Aufzählungen taucht gar nicht als mögliche Option auf – ich sehe wahrscheinlich den Wald vor lauter Bäumen nicht.

Super elegante Lösung auf die man ohne Programmierkenntnisse niemals kommen würde. Ich habe das Script selbst nachgebaut und bin sehr zufrieden. Vielen Dank für die Bereitstellung.

Viele Grüße

Enriko

Vielen Dank für die tolle Anleitung. Ich hatte im javascript Adapter noch kein Haken bei setObject und exec gesetzt und daher hat es bei mir nicht funktioniert und ich habe einen anderen Weg gefunden. Aber werde das Fleiß Übung nochmal wiederholen.

Viele Grüße
Marcus

Super Erklärung. Genau das hatte ich gesucht! Habe das blocky Beispiel umgesetzt. Idee war: Cron Täglich 18-20Uhr, Jede Std. Schaue ob Mülltonne (Typ) ansteht. und gebe mir einen Sound gefolgt von einer Ansage auf alle Amazon fire 7. Es kam mal das eine und mal das andere Tablett, mal nur der Sound und mal nur Text. Jedoch nicht zuverlässig. Mit viel fließ jedes einzeln über eine Subrutine geht…

Welche Ordnerstruktur empfiehlst Du in dem IOBroker anzulegen. Ich sehe immer wieder das Leute deren Sensoren in dem Adapter anlegen andere machen alle Sensoren in einem Ordner , was empfiehlt sich wirklich und was ist smart?

In der Regel wird die Struktur von den Adaptern vorgegeben bzw. eingerichtet. Eigene Datenpunkte kannst du unter 0.userdata anlegen. Viele Grüße

“Wenn du das Script nun manuell, über einen Button in deiner Visualisierung”

Wie bzw mit welchem Widget/Symbol realisiert du es bei Der VIS?
Ansonsten mega. Hab das direkt in mehrere Fällen übernommen.

Mit einem Bool-Button, welches einen Datenpunkt schaltet. Als Quelle nimmst du entweder das Script selbst (unter JavaScript.0.Common) oder einen eigenen Datenpunkt und überwachst ihn mit einem Trigger, der dann die eigentliche Funktion aus dem Artikel enthält. Viele Grüße

Ok. Genauso habe ich es auch gemacht. Würde aber gerne wirklich einen Schalter nehmen. Der also On geht sobald das erste Licht angeschaltet wird. Habe es mit einer immer andauernden Schmeife und Deinem Script hier versucht. Dann bricht aber mein System zusammen wegen fehlendem RAM. Idee?

Ohne dein Script zu kennen, ist es schwierig, das Problem zu erkennen. Ich würde allen Lichter eine Aufzählung zuweisen und auf diese Aufzählung (function) mit dem ID-Selektor (https://www.machs-smart.de/iobroker-blockly-id-selektor/) auf „ist kleiner als letzte“ triggern. Sobald ein Licht in der Aufzählung aus geht (also „falsch“ und somit kleiner als „true“), kannst du einen Datenpunkt schalten.

Ich denke, du hast aktuell einfach eine Dauerschleife programmiert, die dein System in die Knie zwingt.

Okay, danke für die Antwort.Dann werde ich das mal versuchen. Mit welchem Wert muss ich dann den Zustand beschreiben? True oder false stimmt ja dann nicht.
Noch eine Frage, wo finde ich dann den Datenpunkt den ich in ein Widget einfügen kann?
Bin zwar kein blutiger Anfänger mehr, aber so tief bin ich in die Materie noch nicht eingetaucht. Ich lerne gerne weiter.

Schreibe einen Kommentar