ioBroker: Einen einfachen Countdown-Timer erstellen

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Timer mit einem Datenpunkt steuern

Neuen Datenpunkt erstellen

Für einen einfachen Timer, den du über einen einzigen Datenpunkt steuern, starten und stoppen kannst, benötigst du erstmal einen neuen Datenpunkt vom Typ Zahl:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

In diesen Datenpunkt wird die Dauer des Timers als Sekundenwert geschrieben. Gleichzeitig überwacht ein Script, ob in diesen Datenpunkt geschrieben wurde und startet dadurch den Timer.

Blockly-Script aufbauen

Ziehe dir einen Trigger-Block in den Editor und stelle ihn auf wurde geändert. Als Objekt ID wählst du den eben angelegten Datenpunkt. In den Aktionsbereich fügst du einen falls-Block aus dem Bereich Logik ein und stellst diesen über das blaue Zahnrad auf falls — sonst. An den Eingang steckst du den Objekt ID-Block aus dem Bereich Trigger und wählst die Option Wert:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Als Nächstes benötigst du einen timeout-Block sowie einen stop timeout-Block darüber (warum dieser Block hier sinnvoll ist und was er macht, erfährst du in diesem Artikel):

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Füge anschließend einen aktualisiere-Block aus dem Bereich System in den „mache“-Bereich und wähle für die Objekt ID den oben erstellten Datenpunkt „Timer“ aus. Setze dann in das Feld „mit“ den Mathematik-Block 1+1, stelle den Operator auf - und setze statt der ersten Zahl den Objekt ID-Block aus dem Bereich „Trigger“ mit der Option Wert:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Durch diesen Block wird der Datenpunkt mit seinem eigenen Wert, der jede Sekunde um 1 weniger wird, aktualisiert.

Setze in den „sonst“-Bereich eine neue falls-Logik, die abfragt, ob der Countdown vorher manuell gestoppt wurde. Denn wenn du den Countdown manuell (durch eine „0“ – siehe unten) stoppst, war der vorherige Wert sicher größer als „1“ und du erhältst keine Benachrichtigung. Falls dies nicht der Fall ist, erhältst du nach Ablauf des Timers eine Benachrichtigung. Dafür ziehst du an den Eingang des falls-Block einen =-Block aus dem Bereich Logik. In das erste Feld fügst du den Objekt ID-Block aus dem Bereich Trigger und wählst die Option vorheriger Wert. In das zweite Feld setzt du die Zahl 1 aus dem Bereich Mathematik:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

In den „mache“-Bereich setzt du die Aktion, die ausgeführt werden soll, wenn der Timer abgelaufen ist. Zum Beispiel einen sendto-Block oder eine Sprachausgabe über Alexa:

Einen einfachen Timer oder Countdown kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken einfach selbst erstellen. Hier erfährst du, wie das funktioniert.

Starten und Stoppen des Timers

Sobald du den Datenpunkt mit einem Wert befüllst, startet der Timer automatisch und zählt von dem eingegebenen Wert rückwärts bis „0“ und führt dann deine Aktion aus.

Zum Stoppen des Timers schreibst du einfach eine „0“ in den Datenpunkt. Dadurch ist die Bedingung der Logik negativ — Intervall und der Timer werden gestoppt. Mehr über Kurzformen im Logikblock kannst du in diesem Artikel nachlesen.

Timer mit 2. Datenpunkt starten und stoppen

Weiteren Datenpunkt erstellen

Damit der Timer über einen zweiten Datenpunkt gestartet und gestoppt werden kann, benötigst du natürlich einen 2. Datenpunkt vom Typ Logikwert:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Blockly-Script aufbauen

Ziehe dir einen Trigger-Block mit einem externen Eingang in den Editor und stelle ihn auf wurde geändert. Stelle ihn über das blaue Zahnrad auf 2 Eingänge. Als erste Objekt ID wählst du den eben angelegten Datenpunkt. Als zweite Objekt ID wählst du den Datenpunkt „Timer“ aus dem ersten Beispiel.

In den Aktionsbereich fügst du einen falls-Block aus dem Bereich Logik ein und stellst diesen über das blaue Zahnrad auf falls — sonst. An den Eingang steckst du den Wert von Objekt ID-Block aus dem Bereich System mit der Objekt ID des Datenpunkts „Timer-Steuerung“:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Dann benötigst du einen weiteren falls-Block aus dem Bereich Logik. Ziehe ihn dir in den „mache“-Bereich und stecke an den Eingang des Blocks einen Wert von Objekt ID-Block aus dem Bereich System mit der Objekt ID des Datenpunkts „Timer“:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Füge anschließend einen aktualisiere-Block aus dem Bereich System in den „mache“-Bereich und wähle für die Objekt ID den im ersten Beispiel erstellten Datenpunkt „Timer“ aus. Setze dann in das Feld „mit“ den Mathematik-Block 1+1, Stelle den Operator auf - und statt der ersten Zahl einen Wert von Objekt ID-Block aus dem Bereich System mit der Objekt ID des Datenpunkts „Timer“:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Durch diesen Block wird der Datenpunkt „Timer“ mit seinem eigenen Wert, der jede Sekunde um 1 weniger wird, aktualisiert.

In den „sonst“-Bereich steckst du einen umschalten-Block aus dem Bereich System mit der Objekt ID des Datenpunkts „Timer-Steuerung“. Dadurch wird der Datenpunkt „Timer-Steuerung“ automatisch auf „falsch“ gesetzt, wenn der Countdown abgelaufen ist.

Zusätzlich kannst du in den „sonst“-Bereich die Aktion, die ausgeführt werden soll, wenn der Timer abgelaufen ist, einstecken. Zum Beispiel einen sendto-Block oder eine Sprachausgabe über Alexa:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Zuletzt fügst du einen stop timeout-Block in den „sonst“-Bereich des übergeordneten „falls“-Block ein:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Optionale Einstellungen

Möchtest du zusätzlich wissen, ob der Timer abgebrochen wurde oder den Datenpunkt „Timer“ nach Abbruch auf „0“ setzen, fügst du eine weitere falls-Logik in den „sonst“-Bereich des übergeordneten „falls“-Block ein. An den Eingang dieses Blocks steckst du einen Wert von Objekt ID-Block aus dem Bereich System mit der Objekt ID des Datenpunkts „Timer“:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Anschließend setzt du eine Aktion ein, die bei Abbruch gestartet werden soll. Zusätzlich kannst du mit dem System-Block steuere den Datenpunkt „Timer“ zurücksetzen, indem du eine 0 aus dem Bereich Mathematik in das Feld einsetzt:

Einen einfachen Countdown-Timer kannst du mithilfe eines Datenpunkts und ein paar Blockly-Blöcken schnell selbst erstellen. Hier erfährst du, wie das funktioniert.

Starten und Stoppen des Timers

Sobald du den Datenpunkt „Timer-Steuerung“ auf „wahr“ stellst, startet der Timer automatisch und zählt von dem eingegebenen Wert rückwärts bis „0“ und führt dann deine Aktion aus.

Zum Stoppen des Timers stellst du den Datenpunkt einfach wieder auf „falsch“ — Intervall und der Timer werden gestoppt. Mehr über Kurzformen im Logikblock kannst du in diesem Artikel nachlesen.

Fertiges Script

Blockly
<xml xmlns="https://developers.google.com/blockly/xml">
  <variables>
    <variable type="timeout" id="timeout">timeout</variable>
  </variables>
  <block type="on_ext" id="oeda!u0}8(qt14v+zBAq" x="88" y="38">
    <mutation xmlns="http://www.w3.org/1999/xhtml" items="2"></mutation>
    <field name="CONDITION">ne</field>
    <field name="ACK_CONDITION"></field>
    <value name="OID0">
      <shadow type="field_oid" id="VfQYDmTUmKT!IoRs|p*_">
        <field name="oid">0_userdata.0.Timer</field>
      </shadow>
    </value>
    <value name="OID1">
      <shadow type="field_oid" id="Wj=)GF2RzpY0gd8gl_f7">
        <field name="oid">Eigene.0.Timer-Steuerung</field>
      </shadow>
    </value>
    <statement name="STATEMENT">
      <block type="controls_if" id="~3yv9G5%M8{mu8Jb#5-H">
        <mutation else="1"></mutation>
        <value name="IF0">
          <block type="get_value" id="Q(J=,|.c*Mzf-o.FLqkq">
            <field name="ATTR">val</field>
            <field name="OID">Eigene.0.Timer-Steuerung</field>
          </block>
        </value>
        <statement name="DO0">
          <block type="controls_if" id="XdEgOM9cLt/UgPuX*2PS">
            <mutation else="1"></mutation>
            <value name="IF0">
              <block type="get_value" id="),I!o==XH)ALF3??67m.">
                <field name="ATTR">val</field>
                <field name="OID">0_userdata.0.Timer</field>
              </block>
            </value>
            <statement name="DO0">
              <block type="timeouts_cleartimeout" id="Ix1oxVIMw/6InEOx*J1v">
                <field name="NAME">timeout</field>
                <next>
                  <block type="timeouts_settimeout" id="l@}3.P=,2vKmio0`zLBU">
                    <field name="NAME">timeout</field>
                    <field name="DELAY">1000</field>
                    <field name="UNIT">ms</field>
                    <statement name="STATEMENT">
                      <block type="update" id="Ro;pf)L}Y53/I@ojBH~A">
                        <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                        <field name="OID">0_userdata.0.Timer</field>
                        <field name="WITH_DELAY">FALSE</field>
                        <value name="VALUE">
                          <block type="math_arithmetic" id="}QY!Vqv.wC{OGY6siZeY">
                            <field name="OP">MINUS</field>
                            <value name="A">
                              <shadow type="math_number" id="))QJ!OPuyKRR]?YWn.3c">
                                <field name="NUM">1</field>
                              </shadow>
                              <block type="get_value" id="V$ZG03{6.7~(m2rW~NBl">
                                <field name="ATTR">val</field>
                                <field name="OID">0_userdata.0.Timer</field>
                              </block>
                            </value>
                            <value name="B">
                              <shadow type="math_number" id="?Ia}=S/fr0dA|Q`iE)x`">
                                <field name="NUM">1</field>
                              </shadow>
                            </value>
                          </block>
                        </value>
                      </block>
                    </statement>
                  </block>
                </next>
              </block>
            </statement>
            <statement name="ELSE">
              <block type="toggle" id="A%Z%`xgauVNXhZ7JUmh]">
                <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                <field name="OID">Eigene.0.Timer-Steuerung</field>
                <field name="WITH_DELAY">FALSE</field>
              </block>
            </statement>
          </block>
        </statement>
        <statement name="ELSE">
          <block type="timeouts_cleartimeout" id="YF/%*Srl3X[v-?h2~]R~">
            <field name="NAME">timeout</field>
            <next>
              <block type="controls_if" id="uKjC@4wN,B?dDeB4V1E,">
                <value name="IF0">
                  <block type="get_value" id="[yS#c^Q./ZSPmC-wgGa^">
                    <field name="ATTR">val</field>
                    <field name="OID">0_userdata.0.Timer</field>
                  </block>
                </value>
                <statement name="DO0">
                  <block type="control" id="9?ORg0`fdc`;SF{,1F=S">
                    <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                    <field name="OID">0_userdata.0.Timer</field>
                    <field name="WITH_DELAY">FALSE</field>
                    <value name="VALUE">
                      <block type="math_number" id="@tG|2S;P!fa,R^C`m~?%">
                        <field name="NUM">0</field>
                      </block>
                    </value>
                  </block>
                </statement>
              </block>
            </next>
          </block>
        </statement>
      </block>
    </statement>
  </block>
</xml>
Javascript
let timeout;


on({id: new RegExp('0_userdata\\.0\\.Timer' + "|" + 'Eigene\\.0\\.Timer-Steuerung'), change: "ne"}, function (obj) {
    if (getState("Eigene.0.Timer-Steuerung").val) {
    if (getState("0_userdata.0.Timer").val) {
      (function () {if (timeout) {clearTimeout(timeout); timeout = null;}})();
      timeout = setTimeout(function () {
        setState("0_userdata.0.Timer"/*Timer*/, (getState("0_userdata.0.Timer").val - 1), true);
      }, 1000);
    } else {
      getState("Eigene.0.Timer-Steuerung", function (err, state) {
          setState("Eigene.0.Timer-Steuerung"/*Timer-Steuerung*/, state ? !state.val : true);
      });
    }
  } else {
    (function () {if (timeout) {clearTimeout(timeout); timeout = null;}})();
    if (getState("0_userdata.0.Timer").val) {
      setState("0_userdata.0.Timer"/*Timer*/, 0);
    }
  }
});

Ausgabe in einer Visualisierung

Möchtest du den Timer in deiner Visualisierung anzeigen, kannst du das über ein Binding machen. Mehr zu Bindngs erfährst du in diesem Artikel. Folgende Codes kannst du in einem HTML-Widget nutzen:

Gesamtausgabe im Format „X:XX Minuten“

{time:Eigene.0.Timer;Math.floor((time % 3600)/(60))+':'+Math.floor(time % 60)+' Minuten'}

Minutenausgabe

{time:Eigene.0.Timer;Math.floor((time % 3600)/(60))}

Sekundenausgabe

{time:Eigene.0.Timer;Math.floor(time % 60)}
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.

6 Kommentare

Kommentieren

Ich muss mich schon schwer täuschen, aber gibt es nicht zwischenzeitlich für den iobroker einen Adapter Countdown mit dem entsprechenden Blockly Baustein?

Es ist aktuell einer als Beta verfügbar und kommt hoffentlich bald ins Stable-Repository. Bei der obigen Anleitung geht es darum, Verständnis für die Blöcke zu vermitteln. Viele Grüße

Alles gut, funktioniert auch – aber:
Ich möchte den Timer ( sleep ) auf 40 Sekunden setzen. So lange braucht mein Raspi mit Volumio um zu booten.
Dann möchte ich die Instanz Volumio restarten und ein Play absetzen.
Scheinbar läuft der Timer ( sleep) nicht so lange. Muss ich das Systemweit in ioBroker einstellen?
Gruss
Reinhard

Es gibt seit einiger Zeit neue Timerbasierte Blöcke. Es wäre super, wenn die Verwendung dieser Blöcke hier auch erklärt werden könnte.

Ich habe auch eine solche Lösung mir erstellt. Zwar sehr umständlich, aber sie geht immer! Ich habe einen timerDP und einen aliasDP der via boolean abfragt oder der timerDP >0 ist und dann true bzw bei = 0 false ist. Der aliasDP gibt beim manuellen stellen den Wert 29 in den timerDP und bei false sendet er auch den Wert 0 in den timerDP. Mein Script läuft jede Minute ab und fragt ob der aliasDP true ist. Wenn ja dann ziehe vom timerDP eins ab. Solange bis der timerDP = 0 ist. Denn dann springt der aliasDP auf false um.
Warum so kompliziert? Mein ioB hat manchmal Aussetzer und dann würde das Timerscript unterbrochen. So wird immer jede Minute abgefragt ja oder nein und das passt für mich so jetzt perfekt.
Verbesserungsvorschläge?

Schreibe einen Kommentar