Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. Visualisierung der Schalter beim Sonoff TX Ultimate

NEWS

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    15
    1
    535

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    622

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    25
    1
    1.9k

Visualisierung der Schalter beim Sonoff TX Ultimate

Geplant Angeheftet Gesperrt Verschoben Skripten / Logik
1 Beiträge 1 Kommentatoren 28 Aufrufe 2 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • S Offline
    S Offline
    Stefan341
    schrieb am zuletzt editiert von Stefan341
    #1

    Hallo,
    ich habe versucht den Schalterstatus bei meinen Sonoff TX Ultimate zu visualisieren.
    In meinen ersten Versuchen habe ich versucht dies mit Blockly (vielen Dank an @paul53 für die Hilfe) zu realisieren. Allerdings stellte sich schnell raus, dass dies nur sehr unzuverlässig funktioniert (ich vermute wegen den vielen Aufrufen per http).
    Also war die nächste Idee, die Steuerung der LEDs direkt in die Schalter zu verlagern. Da dies relativ schnell, relativ zuverlässig lief, aber es ziemlich dunkel war, wenn die Schalter ausgeschaltet wurden, habe ich noch eine LED-Uhr integriert, die angezeigt wird, wenn alle Kanäle aus sind. Die so entstanden Scripte möchte ich euch natürlich nicht vorenthalten. Sie sind zum größten Teil per KI erstellt und haben einige optische Fehler, also sicherlich für die Experten unter euch verbesserungsfähig. Über Optimierungsvorschläge freue ich mich natürlich.

    Bekannte Fehler:

    * Die Sekunden-LED bleibt schonmal stehen, wird dann beim nächsten erreichen der Sekunden aber wieder "mitgenommen". Ich vermute das hängt mit der periodischen Synchronisation der Uhrzeit zusammen.

    * Selten bleiben die LEDs für Stunden und/oder Minuten trotzdem an wenn ein Kanal eingeschaltet wird.

    So sieht das Ergebnis aus anhand eines 3-Channel Schalters aus:

    IMG_6110.jpeg
    Channel 1 aktiv

    IMG_6111.jpeg
    Channel 2 aktiv

    IMG_6112.jpeg
    Channel 3 aktiv

    Beim 2-Channel entfällt die Anzeige für Channel 2. Es werden also nur die beiden Außenseiten visualisiert.

    Die Visualisierung ist animiert, startet mit der oberen LED und läuft dann nach unten. Beim ausschalten werden die LEDs im umgekehrter Reihenfolge ausgeschaltet.

    Beim 1-Channel beginnt beim Einschalten die LED oben in der Mitte. Danach geht es per "Lauflicht-Effekt" zu beiden Seiten, dann an beiden Seiten nach unten, bis alle LEDs an sind. Das Ausschalten wird entgegengesetzt visualisiert.

    IMG_6115.jpeg
    Anzeige der Uhr wenn alle Schalter Aus sind.
    Stunden -> rot
    Minuten -> grün
    Sekunden -> blau

    Die Farben sind im Script uhr.be per Hex-Code frei wählbar.

    Außerdem ist bei der Uhr ein Dimmer integriert. Um 20:00Uhr werden die LEDs heruntergedimmt und um 8:00Uhr wieder hochgedimmt. Auch diese Zeiten sind im Script anpassbar, sowie die Intensität des Dimmers.

    Um das Ganze einzubauen, wird ein aktives Berry im Schalter benötigt. Um dies zu testen, einfach in der Konsole

    br
    

    eingeben. Kommt keine "unbekannt"-Antwort zurück, ist Berry aktiv.

    Ein etwas seltsames Phänomen, das ich beobachtet habe ist, wenn Berry nicht aktiviert ist, war es bei mir nach der Eingabe von

    Status 0
    

    aktiv.

    Um die Visualisierung einzubauen, müssen drei Dateien über das Filesystem des Schalters erstellt werden. Hier ist es teilweise relevant, ob es sich um einen 1-, 2-, oder 3-Channel Schalter handelt. In den Skripten ist außerdem eingebaut, dass ein Scheme aktiviert wird, wenn keine Uhr eingerichtet ist. Die hat allerdings bei mir nicht wirklich funktioniert. Ob eine Uhr eingerichtet wird oder nicht, wird am Ende mit den Rules bestimmt.

    txu_leds.de (steuert die LEDs wenn die Schalter eingeschaltet werden)
    3-Channel

    # txu_leds.be - Sonoff TX Ultimate 3CH
    # LED-Sequenzen je Relais (rot), rückwärts aus, 0,5s Schritt
    # Clock-Scheme (Uhr) wenn alle Relais aus
    
    # --- Konfiguration ---
    var STEP_MS = 100          # 0,1 s
    var CLOCK_SCHEME = 6       # Uhr-Scheme
    var LED_POWER_CH = 4       # TX Ultimate: Power4
    
    # Farben
    var COL1 = "#FF0000"
    var COL2 = "#FF0000"
    var COL3 = "#FF0000"
    var OFF  = "#000000"
    
    # LED-Reihenfolgen
    var L1 = [22,21,20,19,18,17,16,15,14,13,12]
    var L2 = [24,10]
    var L3 = [26,27,28,1,2,3,4,5,6,7,8]
    
    # --- interner Zustand ---
    var rstate = [0,0,0,0]     # Relais-Zustand (1..3)
    var q = []                 # Job-Queue
    var running = false
    var token = 0
    
    def _cmd(s) tasmota.cmd(s) end
    
    def _led(i, col)
      _cmd(format("LED%d %s", i, col))
    end
    
    # alle LEDs sicher aus
    def all_leds_off()
      for i: range(1, 29)
        _cmd(format("LED%d %s", i, OFF))
      end
    end
    
    def _reverse(arr)
      var out = []
      for i: range(size(arr)-1, -1, -1)
        out.push(arr[i])
      end
      return out
    end
    
    def _any_on()
      return rstate[1] || rstate[2] || rstate[3]
    end
    
    def _all_off()
      return !(rstate[1] || rstate[2] || rstate[3])
    end
    
    # Uhr/Scheme AUS
    def _scheme_off()
      _cmd("Scheme 0")
      _cmd(format("Power%d 1", LED_POWER_CH))
    end
    
    # Uhr/Scheme EIN (nachdem alles aus ist)
    def _scheme_clock_on()
      all_leds_off()
      _cmd(format("Power%d 1", LED_POWER_CH))
      _cmd(format("Scheme %d", CLOCK_SCHEME))
    end
    
    def _enqueue_led_sequence(arr, col, onoff)
      var a = arr
      var c = col
      if !onoff
        a = _reverse(arr)
        c = OFF
      end
      q.push({"arr":a, "col":c})
    end
    
    def _start_worker()
      if running || size(q) == 0
        return
      end
    
      running = true
      token += 1
      var myt = token
    
      var job = q[0]
      q.remove(0)
    
      var arr = job["arr"]
      var col = job["col"]
      var idx = 0
    
      def step()
        if myt != token
          running = false
          _start_worker()
          return
        end
    
        if idx >= size(arr)
          running = false
          if _all_off()
            _scheme_clock_on()
          end
          _start_worker()
          return
        end
    
        _led(arr[idx], col)
        idx += 1
        tasmota.set_timer(STEP_MS, step)
      end
    
      step()
    end
    
    # --- Callback aus Rule ---
    def relay_cb(ch, val)
      var v = int(val)
      rstate[ch] = v
    
      # sobald irgendein Relais an → Uhr aus
      if _any_on()
        _scheme_off()
      end
    
      if ch == 1
        _enqueue_led_sequence(L1, COL1, v)
      elif ch == 2
        _enqueue_led_sequence(L2, COL2, v)
      elif ch == 3
        _enqueue_led_sequence(L3, COL3, v)
      end
    
      _start_worker()
    end
    

    2-Channel

    # txu_leds.be - Sonoff TX Ultimate 2CH
    # LED-Sequenzen je Relais (rot), rückwärts aus, 100ms Schritt
    # Clock-Scheme (Uhr) wenn alle Relais aus
    
    # --- Konfiguration ---
    var STEP_MS = 100          # 0,1 s
    var CLOCK_SCHEME = 5       # Uhr-Scheme
    var LED_POWER_CH = 3       # TX Ultimate: Power3
    
    # Farben
    var COL1 = "#FF0000"
    var COL2 = "#FF0000"
    var OFF  = "#000000"
    
    # LED-Reihenfolgen
    var L1 = [23,22,21,20,19,18,17,16,15,14,13,12,11]
    var L2 = [25,26,27,28,1,2,3,4,5,6,7,8,9]
    
    # --- interner Zustand ---
    var rstate = [0,0,0]       # Relais-Zustand (1..2)
    var q = []                 # Job-Queue
    var running = false
    var token = 0
    
    def _cmd(s) tasmota.cmd(s) end
    
    def _led(i, col)
      _cmd(format("LED%d %s", i, col))
    end
    
    # alle LEDs sicher aus
    def all_leds_off()
      for i: range(1, 29)
        _cmd(format("LED%d %s", i, OFF))
      end
    end
    
    def _reverse(arr)
      var out = []
      for i: range(size(arr)-1, -1, -1)
        out.push(arr[i])
      end
      return out
    end
    
    def _any_on()
      return rstate[1] || rstate[2]
    end
    
    def _all_off()
      return !(rstate[1] || rstate[2])
    end
    
    # Uhr/Scheme AUS
    def _scheme_off()
      _cmd("Scheme 0")
      _cmd(format("Power%d 1", LED_POWER_CH))
    end
    
    # Uhr/Scheme EIN (nachdem alles aus ist)
    def _scheme_clock_on()
      all_leds_off()
      _cmd(format("Power%d 1", LED_POWER_CH))
      _cmd(format("Scheme %d", CLOCK_SCHEME))
    end
    
    def _enqueue_led_sequence(arr, col, onoff)
      var a = arr
      var c = col
      if !onoff
        a = _reverse(arr)
        c = OFF
      end
      q.push({"arr":a, "col":c})
    end
    
    def _start_worker()
      if running || size(q) == 0
        return
      end
    
      running = true
      token += 1
      var myt = token
    
      var job = q[0]
      q.remove(0)
    
      var arr = job["arr"]
      var col = job["col"]
      var idx = 0
    
      def step()
        if myt != token
          running = false
          _start_worker()
          return
        end
    
        if idx >= size(arr)
          running = false
          if _all_off()
            _scheme_clock_on()
          end
          _start_worker()
          return
        end
    
        _led(arr[idx], col)
        idx += 1
        tasmota.set_timer(STEP_MS, step)
      end
    
      step()
    end
    
    # --- Callback aus Rule ---
    def relay_cb(ch, val)
      var v = int(val)
      rstate[ch] = v
    
      # sobald irgendein Relais an → Uhr aus
      if _any_on()
        _scheme_off()
      end
    
      if ch == 1
        _enqueue_led_sequence(L1, COL1, v)
      elif ch == 2
        _enqueue_led_sequence(L2, COL2, v)
      end
    
      _start_worker()
    end
    

    1-Channel

    # txu_leds.be - Sonoff TX Ultimate 1CH
    # LED-Sequenz (rot), Pausen nur an markierten Stellen, 100ms
    # Ausschalten: rückwärts, LEDs aus
    # Clock-Scheme (Uhr) wenn Relais aus
    
    # --- Konfiguration ---
    var STEP_MS = 100          # 100 ms (nur wenn wait=1)
    var CLOCK_SCHEME = 5       # Uhr-Scheme
    var LED_POWER_CH = 2       # TX Ultimate: Power2
    
    # Farben
    var ONCOL = "#FF0000"
    var OFF   = "#000000"
    
    # Sequenz: (led, pause_nachher)
    # "Pause" steht nach: 24,25,26,27,28,1,2,3,4,5,6,7,8,9
    # (23..10 jeweils ohne Pause danach)
    var SEQ = [
      {"led":24, "pause":1},
      {"led":23, "pause":0},
      {"led":25, "pause":1},
      {"led":22, "pause":0},
      {"led":26, "pause":1},
      {"led":21, "pause":0},
      {"led":27, "pause":1},
      {"led":20, "pause":0},
      {"led":28, "pause":1},
      {"led":19, "pause":0},
      {"led":1,  "pause":1},
      {"led":18, "pause":0},
      {"led":2,  "pause":1},
      {"led":17, "pause":0},
      {"led":3,  "pause":1},
      {"led":16, "pause":0},
      {"led":4,  "pause":1},
      {"led":15, "pause":0},
      {"led":5,  "pause":1},
      {"led":14, "pause":0},
      {"led":6,  "pause":1},
      {"led":13, "pause":0},
      {"led":7,  "pause":1},
      {"led":12, "pause":0},
      {"led":8,  "pause":1},
      {"led":11, "pause":0},
      {"led":9,  "pause":1},
      {"led":10, "pause":0}
    ]
    
    # --- interner Zustand ---
    var rstate = [0,0]         # Relais-Zustand (1)
    var q = []                 # Queue von Jobs
    var running = false
    var token = 0
    
    def _cmd(s) tasmota.cmd(s) end
    
    def _led(i, col)
      _cmd(format("LED%d %s", i, col))
    end
    
    def all_leds_off()
      for i: range(1, 29)
        _cmd(format("LED%d %s", i, OFF))
      end
    end
    
    def _any_on()
      return rstate[1]
    end
    
    def _all_off()
      return !rstate[1]
    end
    
    def _scheme_off()
      _cmd("Scheme 0")
      _cmd(format("Power%d 1", LED_POWER_CH))
    end
    
    def _scheme_clock_on()
      all_leds_off()
      _cmd(format("Power%d 1", LED_POWER_CH))
      _cmd(format("Scheme %d", CLOCK_SCHEME))
    end
    
    def _reverse_steps(steps)
      var out = []
      for i: range(size(steps)-1, -1, -1)
        out.push(steps[i])
      end
      return out
    end
    
    def _enqueue_steps(steps, col)
      q.push({"steps":steps, "col":col})
    end
    
    def _start_worker()
      if running || size(q) == 0
        return
      end
    
      running = true
      token += 1
      var myt = token
    
      var job = q[0]
      q.remove(0)
    
      var steps = job["steps"]
      var col = job["col"]
      var idx = 0
    
      def step()
        if myt != token
          running = false
          _start_worker()
          return
        end
    
        if idx >= size(steps)
          running = false
          if _all_off()
            _scheme_clock_on()
          end
          _start_worker()
          return
        end
    
        var s = steps[idx]
        var ledn = s["led"]
        var pause = s["pause"]
    
        _led(ledn, col)
        idx += 1
    
        if pause
          tasmota.set_timer(STEP_MS, step)
        else
          # keine Pause: sofort weiter
          tasmota.set_timer(0, step)
        end
      end
    
      step()
    end
    
    # --- Callback aus Rule ---
    def relay_cb(ch, val)
      var v = int(val)
      rstate[ch] = v
    
      # sobald Relais an → Uhr aus
      if _any_on()
        _scheme_off()
      end
    
      if ch == 1
        if v == 1
          # Einschalten: vorwärts, rot
          _enqueue_steps(SEQ, ONCOL)
        else
          # Ausschalten: rückwärts, LEDs aus
          _enqueue_steps(_reverse_steps(SEQ), OFF)
        end
      end
    
      _start_worker()
    end
    

    Danach folgt die Datei uhr.be (steuert die Uhr wenn alle Channel aus sind). Diese Datei ist für alle Schaltervarianten identisch.

    # uhr.be – TX Ultimate LED-Uhr (kompatibel / stabil)
    # - 28 LEDs (4 Seiten à 7)
    # - 12 Uhr = LED24, 3 Uhr = LED3, 6 Uhr = LED10, 9 Uhr = LED17
    # - Sekunden stabil via Master-Tick (250ms) + "Time" nur 1x/s
    # - Tag/Nacht-Dimmer (variabel)
    # - Resync mit Backoff (kein Time-Spam bei Fehlern)
    # - Generation-Guard gegen Zombie-Timer/Overlap
    
    # =========================
    # Konfiguration
    # =========================
    var BRIGHT_DAY_PCT   = 90
    var BRIGHT_NIGHT_PCT = 2
    
    var NIGHT_START_HOUR = 20
    var DAY_START_HOUR   = 8
    
    var RESYNC_SEC = 60
    
    var COL_SEC  = "0000ff"
    var COL_HOUR = "ff0000"
    var COL_MIN  = "00ff00"
    var COL_HM   = "ffff00"
    
    var TICK_MS = 250
    var TIME_FAIL_BACKOFF_TICKS = 8   # 8*250ms = 2s
    
    # =========================
    # LED-Mapping
    # =========================
    var RING28 = [
      24,25,26,27,28,1,2,
      3,4,5,6,7,8,
      9,10,11,12,13,14,
      15,16,17,18,19,20,
      21,22,23
    ]
    
    var MAP12 = [24,26,1,3,5,8,10,12,15,17,19,22]
    
    def _sec_led(sec)
      return RING28[sec % 28]
    end
    
    # =========================
    # Interner Zustand
    # =========================
    var _timer = nil
    var _running = false
    var _gen = 0
    
    var _hh = 0
    var _mm = 0
    var _ss = 0
    
    var _ticks = 0
    var _subticks = 0
    var _time_fail_cd = 0
    
    var _h_led = 0
    var _m_led = 0
    var _s_led = 0
    
    var _bright_pct = -1
    
    # =========================
    # Helfer
    # =========================
    def _set_led(i, hex)
      tasmota.cmd(format("Led%d %s", i, hex))
    end
    
    def _get_bright_pct(hour)
      if NIGHT_START_HOUR > DAY_START_HOUR
        if hour >= NIGHT_START_HOUR || hour < DAY_START_HOUR
          return BRIGHT_NIGHT_PCT
        end
        return BRIGHT_DAY_PCT
      else
        if hour >= NIGHT_START_HOUR && hour < DAY_START_HOUR
          return BRIGHT_NIGHT_PCT
        end
        return BRIGHT_DAY_PCT
      end
    end
    
    def _scale(hex)
      var r = int("0x"+hex[0..1])
      var g = int("0x"+hex[2..3])
      var b = int("0x"+hex[4..5])
      r = int(r * _bright_pct / 100)
      g = int(g * _bright_pct / 100)
      b = int(b * _bright_pct / 100)
      return format("%02x%02x%02x", r, g, b)
    end
    
    def _read_time()
      var r = tasmota.cmd("Time")
      if r == nil return false end
      var ts = r["Time"]
      if ts == nil || size(ts) < 19 return false end
      _hh = int(ts[11..12])
      _mm = int(ts[14..15])
      _ss = int(ts[17..18])
      return true
    end
    
    def _sync_time()
      if _read_time()
        _ticks = 0
        return true
      end
      return false
    end
    
    # =========================
    # Zeichnen
    # =========================
    def _draw_hm(force)
      var hpos = _hh % 12
      var mpos = int(_mm / 5)
    
      var new_h = MAP12[hpos]
      var new_m = MAP12[mpos]
    
      if _h_led != 0 && _h_led != new_h && _h_led != new_m && _h_led != _s_led
        _set_led(_h_led, "000000")
      end
      if _m_led != 0 && _m_led != new_m && _m_led != new_h && _m_led != _s_led
        _set_led(_m_led, "000000")
      end
    
      if force || new_h != _h_led || new_m != _m_led
        if new_h == new_m
          _set_led(new_h, _scale(COL_HM))
        else
          _set_led(new_h, _scale(COL_HOUR))
          _set_led(new_m, _scale(COL_MIN))
        end
      end
    
      _h_led = new_h
      _m_led = new_m
    end
    
    def _draw_second(force)
      var new_s = _sec_led(_ss)
    
      if _s_led != 0 && _s_led != new_s && _s_led != _h_led && _s_led != _m_led
        _set_led(_s_led, "000000")
      end
    
      if new_s != _h_led && new_s != _m_led
        if force || new_s != _s_led
          _set_led(new_s, _scale(COL_SEC))
        end
      end
    
      _s_led = new_s
    end
    
    def _update_brightness()
      var b = _get_bright_pct(_hh)
      if b != _bright_pct
        _bright_pct = b
        _draw_hm(true)
        _draw_second(true)
      end
    end
    
    def _rebuild()
      _h_led = 0
      _m_led = 0
      _s_led = 0
      _draw_hm(true)
      _draw_second(true)
    end
    
    # =========================
    # Tick
    # =========================
    def _tick()
      if !_running return end
      var g = _gen
    
      # cooldown runterzählen
      if _time_fail_cd > 0
        _time_fail_cd -= 1
      end
    
      _subticks += 1
      if _subticks >= 4
        _subticks = 0
    
        if _time_fail_cd == 0
          if _read_time()
            _update_brightness()
            _draw_hm(false)
            _draw_second(false)
    
            _ticks += 1
            if _ticks >= RESYNC_SEC
              if _sync_time()
                _update_brightness()
                _rebuild()
              else
                _time_fail_cd = TIME_FAIL_BACKOFF_TICKS
              end
            end
          else
            _time_fail_cd = TIME_FAIL_BACKOFF_TICKS
          end
        end
      end
    
      if !_running || g != _gen
        return
      end
      _timer = tasmota.set_timer(TICK_MS, _tick)
    end
    
    # =========================
    # Public API
    # =========================
    def clock_start()
      if _running return end
      tasmota.cmd("Scheme 0")
    
      if _timer != nil
        tasmota.clear_timer(_timer)
        _timer = nil
      end
    
      _gen += 1
    
      _sync_time()
      _bright_pct = _get_bright_pct(_hh)
      _running = true
    
      _subticks = 0
      _time_fail_cd = 0
    
      _rebuild()
      _timer = tasmota.set_timer(TICK_MS, _tick)
    end
    
    def clock_stop()
      _gen += 1
    
      _running = false
      if _timer != nil
        tasmota.clear_timer(_timer)
        _timer = nil
      end
    
      if _s_led != 0 && _s_led != _h_led && _s_led != _m_led
        _set_led(_s_led, "000000")
      end
      if _h_led != 0 _set_led(_h_led, "000000") end
      if _m_led != 0 && _m_led != _h_led
        _set_led(_m_led, "000000")
      end
    
      _h_led = 0
      _m_led = 0
      _s_led = 0
      _bright_pct = -1
      _ticks = 0
      _subticks = 0
      _time_fail_cd = 0
    end
    

    Dann fehlt noch die txu_manager.be. Diese regelt u.a. das laden der Skripte beim booten und bestimmt welches Script aktiv ist (Uhr oder Schalteranimation) Hier muss wieder drauf geachtet werden, welche Schaltervariante verbaut ist. Der Timer am Ende des Scripts bewirkt, dass der Schalter beim Bootvorgang nicht überlastet wird.
    Diese Datei kann weggelassen werden, wenn keine Uhr gewünscht ist.

    3-Channel*

    # txu_manager.be – TX Ultimate 3CH
    
    # Animationsscript laden
    tasmota.cmd('Br load("txu_leds.be")')
    
    # die Uhr laden
    tasmota.cmd('Br load("uhr.be")')
    
    # 3CH: LED-Versorgung über Power4
    var LED_PWR = 4
    
    # von txu_leds.be aufgerufen: Uhr AUS
    def _scheme_off()
      tasmota.cmd(format("Power%d 1", LED_PWR))
      tasmota.cmd("Br clock_stop()")
    end
    
    # von txu_leds.be aufgerufen: Uhr EIN (wenn alle Relais aus)
    def _scheme_clock_on()
      tasmota.cmd(format("Power%d 1", LED_PWR))
      tasmota.cmd("Br clock_start()")
    end
    
    # Boot: Uhr einmal anstoßen (txu_leds.be schaltet sie später korrekt um)
    tasmota.set_timer(20000, /-> tasmota.cmd("Br clock_start()"))
    

    2Channel

    # txu_manager.be – TX Ultimate 2CH
    # verbindet txu_leds.be + uhr.be, ohne txu_leds.be zu ändern
    
    # Scripts laden (runtime-sicher)
    tasmota.cmd('Br load("txu_leds.be")')
    tasmota.cmd('Br load("uhr.be")')
    
    # 2CH: LED-Versorgung über Power3
    var LED_PWR = 3
    
    # Debounce-Timer für Uhr-Start
    var _clock_tmr = nil
    
    def _clock_cancel()
      if _clock_tmr != nil
        tasmota.clear_timer(_clock_tmr)
        _clock_tmr = nil
      end
    end
    
    def _clock_fire()
      _clock_tmr = nil
      tasmota.cmd("Br clock_start()")
    end
    
    # von txu_leds.be aufgerufen: sobald irgendein Relais AN
    def _scheme_off()
      tasmota.cmd(format("Power%d 1", LED_PWR))
      _clock_cancel()
      tasmota.cmd("Br clock_stop()")
    end
    
    # von txu_leds.be aufgerufen: wenn alle Relais AUS (nach Job-Ende)
    def _scheme_clock_on()
      tasmota.cmd(format("Power%d 1", LED_PWR))
      _clock_cancel()
      _clock_tmr = tasmota.set_timer(800, _clock_fire)
    end
    
    # Boot: Uhr anfordern – verzögert, damit kein QPC Reset durch Boot-Last
    tasmota.set_timer(20000, _scheme_clock_on)
    

    1-Channel

    # txu_manager.be – TX Ultimate 1CH
    # verbindet txu_leds.be + uhr.be, ohne txu_leds.be zu ändern
    
    tasmota.cmd('Br load("txu_leds.be")')
    tasmota.cmd('Br load("uhr.be")')
    
    # 1CH: LED-Versorgung über Power2
    var LED_PWR = 2
    
    # Debounce-Timer für Uhr-Start
    var _clock_tmr = nil
    
    def _clock_cancel()
      if _clock_tmr != nil
        tasmota.clear_timer(_clock_tmr)
        _clock_tmr = nil
      end
    end
    
    def _clock_fire()
      _clock_tmr = nil
      tasmota.cmd("Br clock_start()")
    end
    
    # von txu_leds.be aufgerufen: sobald Relais AN
    def _scheme_off()
      tasmota.cmd(format("Power%d 1", LED_PWR))
      _clock_cancel()
      tasmota.cmd("Br clock_stop()")
    end
    
    # von txu_leds.be aufgerufen: wenn Relais AUS (nach Job-Ende)
    def _scheme_clock_on()
      tasmota.cmd(format("Power%d 1", LED_PWR))
      _clock_cancel()
      _clock_tmr = tasmota.set_timer(800, _clock_fire)
    end
    
    # Boot: Uhr anfordern – verzögert, damit Boot-Last nicht resetten kann
    tasmota.set_timer(20000, _scheme_clock_on)
    

    Soweit sind die Dateien fertig. Jetzt geht es in der Konsole weiter:
    Damit die Uhrzeit später auch richtig angezeigt wird, sollte die richtige Zeit im Schalter eingestellt werden.
    Für Deutschland wäre die folgende Eingabe richtig

    Backlog Timezone 99; TimeStd 0,0,10,1,3,60; TimeDst 0,0,3,1,2,120
    

    Als nächstes braucht man eine freie Rule. Da Rule1 und 2 bei mir mit der Verknüpfung des Touch und der Relais belegt ist, habe ich Rule3 genommen.
    Mit der Rule habe ich festgelegt, dass die Datei txu_manager.be beim booten geladen wird. Außerdem werden die LEDs grundsätzlich eingeschaltet.

    Hier muss man jetzt unterscheiden welche Schaltervariante verbaut ist, und ob man die Uhr angezeigt bekommen möchte wenn alle Channel aus sind.

    Rule MIT Uhr (Bei RuleX bitte das "X" mit der Nummer der Rule ersetzen, die man verwenden möchte.
    3-Channel

    ruleX
    ON System#Boot DO Backlog Power4 1; Br load("txu_manager.be") ENDON
    ON Power1#State DO Br relay_cb(1,%value%) ENDON
    ON Power2#State DO Br relay_cb(2,%value%) ENDON
    ON Power3#State DO Br relay_cb(3,%value%) ENDON
    

    2-Channel

    ruleX
    ON System#Boot DO Backlog Power4 1; Br load("txu_manager.be") ENDON
    ON Power1#State DO Br relay_cb(1,%value%) ENDON
    ON Power2#State DO Br relay_cb(2,%value%) ENDON
    ON Power3#State DO Br relay_cb(3,%value%) ENDON
    

    1-Channel

    ruleX
    ON System#Boot DO Backlog Power2 1; Br load("txu_manager.be") ENDON
    ON Power1#State DO Br relay_cb(1,%value%) ENDON
    

    Rule OHNE Uhr (hier wird beim booten nicht die txu_manager.be aufgerufen, sondern die txu_leds.de.

    3-Channel

    ruleX
    ON System#Boot DO Backlog Power4 1; Scheme 6; Br load("txu_leds.be") ENDON
    ON Power1#State DO Br relay_cb(1,%value%) ENDON
    ON Power2#State DO Br relay_cb(2,%value%) ENDON
    ON Power3#State DO Br relay_cb(3,%value%) ENDON
    

    2-Channel

    ruleX
    ON System#Boot DO Backlog Power3 1; Scheme 5; Br load("txu_leds.be") ENDON ON Power1#State DO Br relay_cb(1,%value%) ENDON ON Power2#State DO Br relay_cb(2,%value%) ENDON
    

    1-Channel

    ruleX
    ON System#Boot DO Backlog Power2 1; Scheme 5; Br load("txu_leds.be") ENDON ON Power1#State DO Br relay_cb(1,%value%) ENDON
    

    Wenn jetzt alle Channel ausgeschaltet sind, sollte nach einem Restart mit

    restart 1
    

    bereits die Uhr zu sehen sein. Die Animation der Channel setzt ein, wenn mindestens ein Channel eingeschaltet wird.

    EDIT: uhr.be korrigiert. Sollte jetzt funktionieren ohne das LEDs "hängen bleiben"

    1 Antwort Letzte Antwort
    1
    Antworten
    • In einem neuen Thema antworten
    Anmelden zum Antworten
    • Älteste zuerst
    • Neuste zuerst
    • Meiste Stimmen


    Support us

    ioBroker
    Community Adapters
    Donate

    909

    Online

    32.6k

    Benutzer

    81.9k

    Themen

    1.3m

    Beiträge
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
    ioBroker Community 2014-2025
    logo
    • Anmelden

    • Du hast noch kein Konto? Registrieren

    • Anmelden oder registrieren, um zu suchen
    • Erster Beitrag
      Letzter Beitrag
    0
    • Home
    • Aktuell
    • Tags
    • Ungelesen 0
    • Kategorien
    • Unreplied
    • Beliebt
    • GitHub
    • Docu
    • Hilfe