NEWS
Visualisierung der Schalter beim Sonoff TX Ultimate
-
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 erstelltund 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:

Channel 1 aktiv
Channel 2 aktiv
Channel 3 aktivBeim 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.

Anzeige der Uhr wenn alle Schalter Aus sind.
Stunden -> rot
Minuten -> grün
Sekunden -> blauDie 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
breingeben. 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 0aktiv.
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() end2-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() end1-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() endDanach 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 endDann 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 richtigBacklog Timezone 99; TimeStd 0,0,10,1,3,60; TimeDst 0,0,3,1,2,120Als 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-ChannelruleX 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%) ENDON2-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%) ENDON1-Channel
ruleX ON System#Boot DO Backlog Power2 1; Br load("txu_manager.be") ENDON ON Power1#State DO Br relay_cb(1,%value%) ENDONRule 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%) ENDON2-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%) ENDON1-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%) ENDONWenn jetzt alle Channel ausgeschaltet sind, sollte nach einem Restart mit
restart 1bereits 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"