Skip to content
  • Recent
  • Tags
  • 0 Unread 0
  • Categories
  • Unreplied
  • Popular
  • 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

  • Default (No Skin)
  • No Skin
Collapse
Logo
  1. ioBroker Community Home
  2. Deutsch
  3. Hardware
  4. SONOFF NSPanel mit Lovelace UI

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.0k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    1.8k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    15
    1
    2.0k

SONOFF NSPanel mit Lovelace UI

SONOFF NSPanel mit Lovelace UI

Scheduled Pinned Locked Moved Hardware
lovelace uinspanelsonoff
7.7k Posts 271 Posters 6.7m Views 253 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L ltreff

    @armilar Rule2 ist aus dem Skript:
    Rule2 on Button1#state do Publish %topic%/tele/RESULT {"CustomRecv":"event,button1"} endon on Button2#state do Publish %topic%/tele/RESULT {"CustomRecv":"event,button2"} endon

    Tasten-Config im Skript:
    button1: {
    // DE: Mögliche Werte wenn Rule2 definiert: 'page', 'toggle', 'set' - Wenn nicht definiert --> mode: null
    // EN: Possible values if Rule2 defined: 'page', 'toggle', 'set' - If not defined --> mode: null
    mode: 'toggle',
    // DE: Zielpage - Verwendet wenn mode = page
    // EN: Target page - Used if mode = page
    page: null,
    // DE: Zielentity - Verwendet wenn mode = set oder toggle
    // EN: Target entity - Used if mode = set or toggle
    entity: AliasPath + 'Config.Screensaver.alternativeScreensaverLayout.SET',
    // DE: Zielwert - Verwendet wenn mode = set
    // EN: Target value - Used if mode = set
    setValue: true
    },

    // DE: Konfiguration des rechten Schalters des NSPanels
    // EN: Configuration of the right switch of the NSPanel
    button2: {
        mode: 'toggle',
        page: null,
        entity: AliasPath + 'Config.Screensaver.ScreensaverAdvanced.SET',
        setValue: null
    },
    

    /***** 1. Tasmota-Config *****/

    // DE: Anpassen an die Verzeichnisse der MQTT-Adapter-Instanz
    // EN: Adapt to the MQTT adapter instance directories
    const NSPanelReceiveTopic: string = 'mqtt.0.MyHome.NSPanel1.tele.RESULT';
    const NSPanelSendTopic: string = 'mqtt.0.MyHome.NSPanel1.cmnd.CustomSend';
    

    Objets_mqtt.png

    ArmilarA Offline
    ArmilarA Offline
    Armilar
    Most Active Forum Testing
    wrote on last edited by Armilar
    #6638

    @ltreff

    Rule2 on Button1#state do Publish MyHome/%topic%/tele/RESULT {"CustomRecv":"event,button1"} endon on Button2#state do Publish MyHome/%topic%/tele/RESULT {"CustomRecv":"event,button2"} endon
    Rule2 1
    

    Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
    https://github.com/joBr99/nspanel-lovelace-ui/wiki

    Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

    L 1 Reply Last reply
    2
    • ArmilarA Armilar

      @ltreff

      Rule2 on Button1#state do Publish MyHome/%topic%/tele/RESULT {"CustomRecv":"event,button1"} endon on Button2#state do Publish MyHome/%topic%/tele/RESULT {"CustomRecv":"event,button2"} endon
      Rule2 1
      
      L Offline
      L Offline
      ltreff
      wrote on last edited by
      #6639

      @armilar Das klappt jetzt.
      Der Wechsel der Anzeige ist auch noch vom Wert 0_userdata.0.NSPanel.1.Config.Screensaver.timeoutScreensaver abhängig.

      Vielen Dank, ich beende dann diesen Topic.

      1 Reply Last reply
      1
      • K Kuckuckmann

        @losossos & @tomsport2022

        Ich habe das Thema die Tage mit Armilar diskutiert und wir haben es auf der Roadmap auf dem Screensaver neben den Wetter-Daten und dem Wetter-Forcast noch weitere - ich nenne es mal "Reihen" - einzuführen, die man dann individuell belegen kann. Wir denken auch darüber nach, dann x zusätzliche dynamisch verwendbare "Reihen" hinzuzufügen.
        Dafür müssen wir aber an der jetzigen Logik ein wenig arbeiten.

        Ich kann noch nicht sagen, wann genau wir diese Ergänzung haben werden, nur so viel, es steht auf dem ToDo Zettel 🙂

        @losossos Du kannst das XML vom Blockly (Export Button nutzen) hier als Spoiler rein packen, dann kann man es sich ziehen und importieren. Wärst Du so nett es zu posten?
        Dein Ansatz klingt durchaus interessant.

        L Offline
        L Offline
        losossos
        wrote on last edited by
        #6640

        @kuckuckmann

        Mahlzeit, ist schon 'ne Weile her seit meinem letztem post.
        Ich habe eine Frage zur Aktualisierung bzw. Aktivierung des Screensavers;
        Wie gesagt, ich hab lange nichts mehr an den Panels "gemacht". Alles lief prima und das Motto ist ja beakanntlicher Weise "never touch a running...."
        Nun habe ich aber doch mal wieder etwas angepasst/hinzugefügt und dabei dann auch das Skript von v 4.3.1 auf aktuell hochgezogen. Soweit läuft alles. Allerdings ist es jetzt so, daß mein Wetterscreensaver (accuweather) nicht mehr (automatisch) aktiviert wird wenn ich zuvor ne popup-nachricht 0_userdata.0.NSPanel.2.ScreensaverInfo.popupNotifyHeading und 0_userdata.0.NSPanel.2.ScreensaverInfo.popupNotifyText ausgegeben habe. Zuvor war es so, daß nach einem timeout der Wetter screensaver automatisch wieder aktiviert wurde. Jetzt klappt das nur noch wenn ich das Display kurz "antatsche".
        (ich zeige in bestimmten Abständen diverse "news" über diese Infozeilen an)
        An welcher "Schraube müßte ich denn drehen" ums wieder so hinzubekommen wie's zuvor war?

        T 1 Reply Last reply
        0
        • L losossos

          @kuckuckmann

          Mahlzeit, ist schon 'ne Weile her seit meinem letztem post.
          Ich habe eine Frage zur Aktualisierung bzw. Aktivierung des Screensavers;
          Wie gesagt, ich hab lange nichts mehr an den Panels "gemacht". Alles lief prima und das Motto ist ja beakanntlicher Weise "never touch a running...."
          Nun habe ich aber doch mal wieder etwas angepasst/hinzugefügt und dabei dann auch das Skript von v 4.3.1 auf aktuell hochgezogen. Soweit läuft alles. Allerdings ist es jetzt so, daß mein Wetterscreensaver (accuweather) nicht mehr (automatisch) aktiviert wird wenn ich zuvor ne popup-nachricht 0_userdata.0.NSPanel.2.ScreensaverInfo.popupNotifyHeading und 0_userdata.0.NSPanel.2.ScreensaverInfo.popupNotifyText ausgegeben habe. Zuvor war es so, daß nach einem timeout der Wetter screensaver automatisch wieder aktiviert wurde. Jetzt klappt das nur noch wenn ich das Display kurz "antatsche".
          (ich zeige in bestimmten Abständen diverse "news" über diese Infozeilen an)
          An welcher "Schraube müßte ich denn drehen" ums wieder so hinzubekommen wie's zuvor war?

          T Offline
          T Offline
          TT-Tom
          wrote on last edited by
          #6641

          @losossos

          Ja da hat sich in der Zeit einiges geändert. Hier kannst du alles nachlesen.
          https://github.com/joBr99/nspanel-lovelace-ui/wiki/Changelog
          https://github.com/joBr99/nspanel-lovelace-ui/wiki/Release-Notes

          und hier die Lösung für dein Problem
          https://github.com/joBr99/nspanel-lovelace-ui/wiki/ioBroker-Config-Screensaver#popupnotify-im-screensaver

          Gruß Tom
          https://github.com/tt-tom17
          Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

          NSPanel Script Wiki
          https://github.com/joBr99/nspanel-lovelace-ui/wiki

          NSPanel Adapter Wiki
          https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

          L 1 Reply Last reply
          2
          • T TT-Tom

            @losossos

            Ja da hat sich in der Zeit einiges geändert. Hier kannst du alles nachlesen.
            https://github.com/joBr99/nspanel-lovelace-ui/wiki/Changelog
            https://github.com/joBr99/nspanel-lovelace-ui/wiki/Release-Notes

            und hier die Lösung für dein Problem
            https://github.com/joBr99/nspanel-lovelace-ui/wiki/ioBroker-Config-Screensaver#popupnotify-im-screensaver

            L Offline
            L Offline
            losossos
            wrote on last edited by
            #6642

            @tt-tom said in SONOFF NSPanel mit Lovelace UI:

            Ja da hat sich in der Zeit einiges geändert.

            Oh, ja da hat sich ne ganze Menge getan! Gute Arbeit 👍 😊

            @tt-tom said in SONOFF NSPanel mit Lovelace UI:

            und hier die Lösung für dein Problem

            Supi, klar , hätt natürlich auch alles nachlesen können, aber so geht's natürlich viiiiiel schneller.
            1000-Dank und schöne 🎅 🎄

            1 Reply Last reply
            1
            • K Offline
              K Offline
              Kerschte_de
              wrote on last edited by Kerschte_de
              #6643

              Guten Abend zusammen.
              Mein Test-NSPanel hatte ich mit Eurer Unterstützung zum Funktionieren bekommen. Die Kommunikation zwischen Panel und ioB lief.
              Inzwischen habe ich meine beiden ioB-Instanzen zu einer neuen und einzigen ioB-Instanz neu aufgesetzt (jetzt kein Raspi mehr, sondern in miniPC (Proxmox). Entsprechend habe ich versucht, auch das Panel umzuziehen. Geflasht und eingerichtet war es ja bereits, also habe ich lediglich auf NSPanel-Tasmota die neue IPv4 hinterlegt. Meinen extern geführten MQTT-Broker habe ich entsprechend der Empfehlung auf einen neuen Port umgestellt ... und ebenfalls im Tasmota des NSPanels aktualisiert.
              Die Ojektzeile "mqtt.0.RagowSmartHome.NSPanel_85C180.cmnd.CustomSend" habe ich über einen MQTT-Explorer angelegt. Das hatte funktioniert. Jedoch fiel mir dabei auf, dass ich nicht aus der Konsole des NSPanels heraus einen Befehl übermitteln konnte.
              Inzwischen kommuniziert die Wetter-App mit dem Screensaver auf dem NSP. Auch Seiten kann ich im TS-Script des ioB anlegen. TS-Script habe ich auf der neuesten Version. Leider werden aber keine darin verknüpften Werte übertragen. Ich habe alles probiert, was ich mir von Euch dazu anlesen konnte. Ich bekomme es jedoch nicht wieder hin.
              Meine Vermutung ist, dass es irgendwie mit dem Abo auf die beiden mqtt-Datenpunkte nicht ganz klappt (CustomSend und stat.RESULT). Dazu kenne ich aber auch nicht die Funktionsweise des Panels, was worüber kommuniziert wird. Wie erwähnt, Wetter im Screensaver und eigene Seitenstrukturen gehen, aber keine Werte/Datenpunkte. Kann mich bitte jemand begleiten, den Fehler bei mir systematisch einzugrenzen?

              T 1 Reply Last reply
              0
              • K Kerschte_de

                Guten Abend zusammen.
                Mein Test-NSPanel hatte ich mit Eurer Unterstützung zum Funktionieren bekommen. Die Kommunikation zwischen Panel und ioB lief.
                Inzwischen habe ich meine beiden ioB-Instanzen zu einer neuen und einzigen ioB-Instanz neu aufgesetzt (jetzt kein Raspi mehr, sondern in miniPC (Proxmox). Entsprechend habe ich versucht, auch das Panel umzuziehen. Geflasht und eingerichtet war es ja bereits, also habe ich lediglich auf NSPanel-Tasmota die neue IPv4 hinterlegt. Meinen extern geführten MQTT-Broker habe ich entsprechend der Empfehlung auf einen neuen Port umgestellt ... und ebenfalls im Tasmota des NSPanels aktualisiert.
                Die Ojektzeile "mqtt.0.RagowSmartHome.NSPanel_85C180.cmnd.CustomSend" habe ich über einen MQTT-Explorer angelegt. Das hatte funktioniert. Jedoch fiel mir dabei auf, dass ich nicht aus der Konsole des NSPanels heraus einen Befehl übermitteln konnte.
                Inzwischen kommuniziert die Wetter-App mit dem Screensaver auf dem NSP. Auch Seiten kann ich im TS-Script des ioB anlegen. TS-Script habe ich auf der neuesten Version. Leider werden aber keine darin verknüpften Werte übertragen. Ich habe alles probiert, was ich mir von Euch dazu anlesen konnte. Ich bekomme es jedoch nicht wieder hin.
                Meine Vermutung ist, dass es irgendwie mit dem Abo auf die beiden mqtt-Datenpunkte nicht ganz klappt (CustomSend und stat.RESULT). Dazu kenne ich aber auch nicht die Funktionsweise des Panels, was worüber kommuniziert wird. Wie erwähnt, Wetter im Screensaver und eigene Seitenstrukturen gehen, aber keine Werte/Datenpunkte. Kann mich bitte jemand begleiten, den Fehler bei mir systematisch einzugrenzen?

                T Offline
                T Offline
                TT-Tom
                wrote on last edited by TT-Tom
                #6644

                @kerschte_de

                Setze das Script bitte in den Debug-Modus und starte es neu, dann poste das Log vom Start des Script bis zum erscheinen des Screensaver.

                Debugmodus im Panel unter Einstellung -> Script -> Debug Modus(an/aus)
                oder im Script unter

                // DE: liefert bei true detailliertere Meldundgen im Log.
                // EN: if true, provides more detailed messages in the log.
                var Debug: boolean = true;
                

                Gruß Tom
                https://github.com/tt-tom17
                Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

                NSPanel Script Wiki
                https://github.com/joBr99/nspanel-lovelace-ui/wiki

                NSPanel Adapter Wiki
                https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

                K 1 Reply Last reply
                0
                • T TT-Tom

                  @kerschte_de

                  Setze das Script bitte in den Debug-Modus und starte es neu, dann poste das Log vom Start des Script bis zum erscheinen des Screensaver.

                  Debugmodus im Panel unter Einstellung -> Script -> Debug Modus(an/aus)
                  oder im Script unter

                  // DE: liefert bei true detailliertere Meldundgen im Log.
                  // EN: if true, provides more detailed messages in the log.
                  var Debug: boolean = true;
                  
                  K Offline
                  K Offline
                  Kerschte_de
                  wrote on last edited by
                  #6645

                  @tt-tom
                  Hallo Tom. Vielen Dank, dass Du Dich der Sache so schnell annimmst. Ich bin gerade auch nochmal das Video von Matthias durchgegangen, ob ich irgendwas entdecke ... habe einige Datenpunkte auch nochmal exakt nach seinem Video angelegt und dann im Script hinterlegt. Leider weiter ohne Erfolg.

                  14.12.2024, 18:20:28.125	[info ]: javascript.0 (363) Compiling TypeScript source script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT
                  14.12.2024, 18:20:28.391	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: source code did not change, using cached compilation result...
                  14.12.2024, 18:20:28.456	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: --- start of NsPanelTs: 0_userdata.0.NSPanel.1. ---
                  14.12.2024, 18:20:28.459	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: setObjects enabled - create Alias Channels possible
                  14.12.2024, 18:20:28.460	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: weather alias for accuweather.0. already exists
                  14.12.2024, 18:20:28.464	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: registered 41 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                  14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Desired TFT Firmware: 53 / v4.4.0
                  14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Installed TFT Firmware: 53 / v4.4.0
                  14.12.2024, 18:20:28.720	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Debug mode activated
                  14.12.2024, 18:20:28.788	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Tasmota Buzzer disabled
                  14.12.2024, 18:20:28.800	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: NaN W
                  14.12.2024, 18:20:28.801	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                  14.12.2024, 18:20:28.809	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting tasmota firmware version
                  14.12.2024, 18:20:28.810	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting current berry driver version
                  14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                  14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online berry driver version
                  14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online TFT version
                  14.12.2024, 18:20:28.813	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online firmware version
                  14.12.2024, 18:20:28.828	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: import adbase as ad
                  
                  from luibackend.config import LuiBackendConfig
                  from luibackend.controller import LuiController
                  from luibackend.mqtt import LuiMqttListener, LuiMqttSender
                  from luibackend.updater import Updater
                  
                  import apis
                  import json
                  from typing import Literal
                  
                  class NsPanelLovelaceUIManager(ad.ADBase):
                  
                      def initialize(self):
                          self.adapi = self.get_ad_api()
                          self.adapi.log('Starting')
                          apis.ad_api = self.adapi
                          apis.ha_api   = self.get_plugin_api("HASS")
                          apis.mqtt_api = self.get_plugin_api("MQTT")
                  
                          cfg = self._cfg = LuiBackendConfig(apis.ha_api, self.args["config"])
                  
                          use_api = cfg.get("use_api") == True
                  
                          topic_send = cfg.get("panelSendTopic")
                          topic_recv = cfg.get("panelRecvTopic")
                          api_panel_name = cfg.get("panelName")
                          api_device_id = cfg.get("panelDeviceId")
                          quiet = cfg.get("quiet")
                  
                          mqttsender = self._mqttsender = LuiMqttSender(apis.ha_api, use_api, topic_send, api_panel_name, quiet)
                  
                          self._controller = LuiController(cfg, mqttsender.send_mqtt_msg)
                          
                          desired_tasmota_driver_version   = 8
                          desired_display_firmware_version = 53
                          version     = "v4.3.3"
                          
                          model       = cfg.get("model")
                          if model == "us-l":
                              desired_display_firmware_url = cfg._config.get("displayURL-US-L", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft")
                          elif model == "us-p":
                              desired_display_firmware_url = cfg._config.get("displayURL-US-P", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft")
                          else:
                              desired_display_firmware_url = cfg._config.get("displayURL-EU",   f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft")
                          desired_tasmota_driver_url       = cfg._config.get("berryURL",         "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be")
                  
                          mode = cfg.get("updateMode")
                          updater = Updater(self.adapi.log, mqttsender, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
                          
                          # Request Tasmota Driver Version
                          updater.request_berry_driver_version()
                  
                          LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, self._controller, updater)
                  
                          self.adapi.log(f'Started ({version})')
                          
                      #
                      # helpers
                      #
                      
                      def show_card(self, card_key: str) -> None:
                          """Used to show card on panel"""
                          
                          msg = json.dumps({"CustomRecv":f"event,buttonPress2,navigate.{card_key},button"})
                          topic = self._cfg.get("panelRecvTopic")
                          self._mqttsender.send_mqtt_msg(msg, topic)
                          
                      def navigate(self, direction: Literal['up', 'prev', 'next']) -> None:
                          """Used to navigate different directions on the panel"""
                          
                          msg = json.dumps({"CustomRecv":f"event,buttonPress2,nav{direction.title()},button"})
                          topic = self._cfg.get("panelRecvTopic")
                          self._mqttsender.send_mqtt_msg(msg, topic)
                          
                      @property
                      def current_card(self) -> str:
                          """Used to get the panel's current card"""
                          
                          return self._controller.current_card.key
                  
                  14.12.2024, 18:20:28.832	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: # Sonoff NSPanel Tasmota Lovelace UI Berry Driver (Extended Flashing to faster speeds; improved Error Handling)| code by joBr99
                  # based on;
                  # Sonoff NSPanel Tasmota (Nextion with Flashing) driver | code by peepshow-21
                  # based on;
                  # Sonoff NSPanel Tasmota driver v0.47 | code by blakadder and s-hadinger
                  
                  # Example Flash
                  # FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft
                  # FlashNextion http://nspanel.pky.eu/lui.tft
                  
                  class Nextion : Driver
                  
                      static header = bytes('55BB')
                  
                      static flash_block_size = 4096
                  
                      var flash_mode
                      var flash_start_millis
                      var flash_size
                      var flash_written
                      var flash_buff
                      var flash_offset
                      var flash_proto_version
                      var flash_proto_baud
                      var awaiting_offset
                      var tcp
                      var ser
                      var last_per
                      var url
                  
                      def split_55(b)
                        var ret = []
                        var s = size(b)   
                        var i = s-2   # start from last-1
                        while i > 0
                          if b[i] == 0x55 && b[i+1] == 0xBB           
                            ret.push(b[i..s-1]) # push last msg to list
                            b = b[(0..i-1)]   # write the rest back to b
                          end
                          i -= 1
                        end
                        ret.push(b)
                        return ret
                      end
                  
                      def crc16(data, poly)
                        if !poly  poly = 0xA001 end
                        # CRC-16 MODBUS HASHING ALGORITHM
                        var crc = 0xFFFF
                        for i:0..size(data)-1
                          crc = crc ^ data[i]
                          for j:0..7
                            if crc & 1
                              crc = (crc >> 1) ^ poly
                            else
                              crc = crc >> 1
                            end
                          end
                        end
                        return crc
                      end
                  
                      # encode using custom protocol 55 BB [payload length] [payload length] [payload] [crc] [crc]
                      def encode(payload)
                        var b = bytes()
                        b += self.header
                        b.add(size(payload), 2)   # add size as 2 bytes, little endian
                        b += bytes().fromstring(payload)
                        var msg_crc = self.crc16(b)
                        b.add(msg_crc, 2)       # crc 2 bytes, little endian
                        return b
                      end
                  
                      def encodenx(payload)
                          var b = bytes().fromstring(payload)
                          b += bytes('FFFFFF')
                          return b
                      end
                  
                      def sendnx(payload)
                          import string
                          var payload_bin = self.encodenx(payload)
                          self.ser.write(payload_bin)
                          log(string.format("NXP: Nextion command sent = %s",str(payload_bin)), 3)       
                      end
                  
                      def send(payload)
                          var payload_bin = self.encode(payload)
                          if self.flash_mode==1
                              log("NXP: skipped command becuase still flashing", 3)
                          else 
                              self.ser.write(payload_bin)
                              log("NXP: payload sent = " + str(payload_bin), 3)
                          end
                      end
                  
                      def write_to_nextion(b)
                          self.ser.write(b)
                      end
                  
                      def screeninit()
                          log("NXP: Screen Initialized")
                          self.sendnx("recmod=1")        
                      end
                  
                      def write_block()
                          
                          import string
                          log("FLH: Read block",3)
                          while size(self.flash_buff)<self.flash_block_size && self.tcp.connected()
                              if self.tcp.available()>0
                                  self.flash_buff += self.tcp.readbytes(4096)
                              else
                                  tasmota.delay(50)
                                  log("FLH: Wait for available...",3)
                              end
                          end
                          log("FLH: Buff size "+str(size(self.flash_buff)),3)
                          var to_write
                          if size(self.flash_buff)>self.flash_block_size
                              to_write = self.flash_buff[0..self.flash_block_size-1]
                              self.flash_buff = self.flash_buff[self.flash_block_size..]
                          else
                              to_write = self.flash_buff
                              self.flash_buff = bytes()
                          end
                          log("FLH: Writing "+str(size(to_write)),3)
                          var per = (self.flash_written*100)/self.flash_size
                          if (self.last_per!=per) 
                              self.last_per = per
                              tasmota.publish_result(string.format("{\"Flashing\":{\"complete\": %d, \"time_elapsed\": %d}}",per , (tasmota.millis()-self.flash_start_millis)/1000), "RESULT") 
                          end
                          if size(to_write)>0
                              self.flash_written += size(to_write)
                              self.ser.write(to_write)
                          end
                          log("FLH: Total "+str(self.flash_written),3)
                          if (self.flash_written==self.flash_size)
                              log("FLH: Flashing complete - Time elapsed: %d", (tasmota.millis()-self.flash_start_millis)/1000)
                              self.flash_mode = 0
                              self.ser.deinit()
                              self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                          end
                  
                      end
                  
                      def every_100ms()
                          import string
                          if self.ser.available() > 0
                              var msg = self.ser.read()
                              if size(msg) > 0
                                  log(string.format("NXP: Received Raw = %s",str(msg)), 3)
                                  if (self.flash_mode==1)
                                      var strv = msg[0..-4].asstring()
                                      if string.find(strv,"comok 2")>=0
                                          tasmota.delay(50)
                                          log("FLH: Send (High Speed) flash start")
                                          self.flash_start_millis = tasmota.millis()
                                          #self.sendnx(string.format("whmi-wris %d,115200,res0",self.flash_size))
                                          if self.flash_proto_version == 0
                                              self.sendnx(string.format("whmi-wri %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                          else
                                              self.sendnx(string.format("whmi-wris %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                          end
                                          if self.flash_proto_baud != 115200
                                              tasmota.delay(50)
                                              self.ser.deinit()
                                              self.ser = serial(17, 16, self.flash_proto_baud, serial.SERIAL_8N1)
                                          end
                                      elif size(msg)==1 && msg[0]==0x08
                                          log("FLH: Waiting offset...",3)
                                          self.awaiting_offset = 1
                                      elif size(msg)==4 && self.awaiting_offset==1
                                          self.awaiting_offset = 0
                                          self.flash_offset = msg.get(0,4)
                                          log("FLH: Flash offset marker "+str(self.flash_offset),3)
                                          if self.flash_offset != 0
                                              self.open_url_at(self.url, self.flash_offset)
                                              self.flash_written = self.flash_offset
                                          end
                                          self.write_block()
                                      elif size(msg)==1 && msg[0]==0x05
                                          self.write_block()
                                      else
                                          log("FLH: Something has gone wrong flashing display firmware ["+str(msg)+"]",2)
                                      end
                                  else
                                      var msg_list = self.split_55(msg)
                                      for i:0..size(msg_list)-1
                                          msg = msg_list[i]
                                          if size(msg) > 0
                                              if msg == bytes('000000FFFFFF88FFFFFF')
                                                  self.screeninit()
                                              elif size(msg)>=2 && msg[0]==0x55 && msg[1]==0xBB
                                                  var jm = string.format("{\"CustomRecv\":\"%s\"}",msg[4..-3].asstring())
                                                  tasmota.publish_result(jm, "RESULT")        
                                              elif msg[0]==0x07 && size(msg)==1 # BELL/Buzzer
                                                  tasmota.cmd("buzzer 1,1")
                                              else
                                                  var jm = string.format("{\"nextion\":\"%s\"}",str(msg[0..-4]))
                                                  tasmota.publish_result(jm, "RESULT")        
                                              end
                                          end       
                                      end
                                  end
                              end
                          end
                      end      
                  
                      def begin_nextion_flash()
                          self.flash_written = 0
                          self.awaiting_offset = 0
                          self.flash_offset = 0
                          self.sendnx('DRAKJHSUYDGBNCJHGJKSHBDN')
                          self.sendnx('recmod=0')
                          self.sendnx('recmod=0')
                          self.flash_mode = 1
                          self.sendnx("connect")        
                      end
                      
                      def open_url_at(url, pos)
                          self.url = url
                          import string
                          var host
                          var port
                          var s1 = string.split(url,7)[1]
                          var i = string.find(s1,":")
                          var sa
                          if i<0
                              port = 80
                              i = string.find(s1,"/")
                              sa = string.split(s1,i)
                              host = sa[0]
                          else
                              sa = string.split(s1,i)
                              host = sa[0]
                              s1 = string.split(sa[1],1)[1]
                              i = string.find(s1,"/")
                              sa = string.split(s1,i)
                              port = int(sa[0])
                          end
                          var get = sa[1]
                          log(string.format("FLH: host: %s, port: %s, get: %s",host,port,get))
                          self.tcp = tcpclient()
                          self.tcp.connect(host,port)
                          log("FLH: Connected:"+str(self.tcp.connected()),3)
                          var get_req = "GET "+get+" HTTP/1.0\r\n"
                          get_req += string.format("Range: bytes=%d-\r\n", pos)
                          get_req += string.format("HOST: %s:%s\r\n\r\n",host,port)
                          self.tcp.write(get_req)
                          var a = self.tcp.available()
                          i = 1
                          while a==0 && i<5
                            tasmota.delay(100*i)
                            tasmota.yield() 
                            i += 1
                            log("FLH: Retry "+str(i),3)
                            a = self.tcp.available()
                          end
                          if a==0
                              log("FLH: Nothing available to read!",3)
                              return
                          end
                          var b = self.tcp.readbytes()
                          i = 0
                          var end_headers = false;
                          var headers
                          while i<size(b) && headers==nil
                              if b[i..(i+3)]==bytes().fromstring("\r\n\r\n") 
                                  headers = b[0..(i+3)].asstring()
                                  self.flash_buff = b[(i+4)..]
                              else
                                  i += 1
                              end
                          end
                          #print(headers)
                          # check http respose for code 200/206
                          if string.find(headers,"200 OK")>0 || string.find(headers,"206 Partial Content")>0
                              log("FLH: HTTP Respose is 200 OK or 206 Partial Content",3)
                          else
                              log("FLH: HTTP Respose is not 200 OK or 206 Partial Content",3)
                              print(headers)
                              return -1
                          end
                          # only set flash size if pos is zero
                          if pos == 0
                              # check http respose for content-length
                              var tag = "Content-Length: "
                              i = string.find(headers,tag)
                              if (i>0) 
                                  var i2 = string.find(headers,"\r\n",i)
                                  var s = headers[i+size(tag)..i2-1]
                                  self.flash_size=int(s)
                              end
                              log("FLH: Flash file size: "+str(self.flash_size),3)
                          end
                  
                      end
                  
                      def flash_nextion(url)
                          self.flash_size = 0
                          var res = self.open_url_at(url, 0)
                          if res != -1
                              self.begin_nextion_flash()
                          end
                      end
                  
                      def init()
                          log("NXP: Initializing Driver")
                          self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                          self.flash_mode = 0
                          self.flash_proto_version = 1
                          self.flash_proto_baud = 921600
                      end
                  
                  end
                  
                  var nextion = Nextion()
                  
                  tasmota.add_driver(nextion)
                  
                  def get_current_version(cmd, idx, payload, payload_json)
                      import string
                      var version_of_this_script = 9
                      var jm = string.format("{\"nlui_driver_version\":\"%s\"}", version_of_this_script)
                      tasmota.publish_result(jm, "RESULT")
                  end
                  
                  tasmota.add_cmd('GetDriverVersion', get_current_version)
                  
                  def update_berry_driver(cmd, idx, payload, payload_json)
                      def task()
                          import path
                          import string
                  		if string.find(payload, ".tapp") > 0
                  		    print("tapp in URL; will do .tapp update and migration if necessary")
                  			
                  			if path.exists("autoexec.be")
                  			    print("autoexec.be found; will check for migration")
                  				var autoexecfile = open('autoexec.be')
                  				var line = autoexecfile.readline()
                  				autoexecfile.close()
                  				if string.find(line, "NSPanel Tasmota Lovelace UI Berry Driver") > 0
                  			        print("found lovelace berry driver, going to delete autoexec.be and .bec")
                  					path.remove("autoexec.be")
                  					path.remove("autoexec.bec")
                  				end
                  			end
                  			
                  			var r = tasmota.urlfetch(payload, "nsp-lovelace-driver.tapp")
                              if r < 0
                                  print("Update failed")
                              else
                                  tasmota.cmd("Restart 1")
                              end
                  			
                  		elif string.find(payload, ".be") > 0
                  		    print("be in URL; will do .be update")
                  			if path.exists("nsp-lovelace-driver.tapp")
                  			    print("Error: there is the tapp version of the berry driver installed; cannot do .be update.")
                  			else
                                  var cl = webclient()
                                  cl.begin(payload)
                                  var r = cl.GET()
                                  if r == 200
                                      print("Sucessfully downloaded nspanel-lovelace-ui berry driver")
                                  else
                                      print("Error while downloading nspanel-lovelace-ui berry driver")
                                  end
                                  r = cl.write_file("autoexec.be")
                                  if r < 0
                                      print("Error while writeing nspanel-lovelace-ui berry driver")
                                  else
                                      print("Sucessfully written nspanel-lovelace-ui berry driver")
                                      tasmota.cmd("Restart 1")
                                  end
                  			end
                  		else
                  			print("invalid url filetype")
                  		end
                  		
                  		
                  		
                          if path.exists("nsp-lovelace-driver.tapp")
                              var r = string.find(payload, ".tapp")
                              if r < 0
                                  print("URL doesn't contain .tapp skipping update")
                              else
                  
                              end
                          else
                              var r = string.find(payload, ".be")
                              if r < 0
                                  print("URL doesn't contain .be skipping update")
                              else
                          
                              end                
                          end
                      end
                      tasmota.set_timer(0,task)
                      tasmota.resp_cmnd_done()
                  end
                  
                  tasmota.add_cmd('UpdateDriverVersion', update_berry_driver)
                  
                  def flash_nextion(cmd, idx, payload, payload_json)
                      def task()
                      nextion.flash_proto_version = 1
                      nextion.flash_proto_baud = 921600
                          nextion.flash_nextion(payload)
                      end
                      tasmota.set_timer(0,task)
                      tasmota.resp_cmnd_done()
                  end
                  
                  def flash_nextion_adv(cmd, idx, payload, payload_json)
                      def task()        
                          if idx==0
                              nextion.flash_proto_version = 1
                              nextion.flash_proto_baud = 921600
                          elif idx==1
                              nextion.flash_proto_version = 0
                              nextion.flash_proto_baud = 921600
                          elif idx==2
                              nextion.flash_proto_version = 1
                              nextion.flash_proto_baud = 115200
                          elif idx==3
                              nextion.flash_proto_version = 0
                              nextion.flash_proto_baud = 115200
                          elif idx==4
                              nextion.flash_proto_version = 1
                              nextion.flash_proto_baud = 256000
                          elif idx==5
                              nextion.flash_proto_version = 0
                              nextion.flash_proto_baud = 256000
                          elif idx==6
                              nextion.ser.deinit()
                              nextion.ser = serial(17, 16, 9600, serial.SERIAL_8N1)
                              nextion.flash_proto_version = 0
                              nextion.flash_proto_baud = 921600
                          else
                              nextion.flash_proto_version = 0
                              nextion.flash_proto_baud = 115200
                          end
                          
                          nextion.flash_nextion(payload)
                      end
                      tasmota.set_timer(0,task)
                      tasmota.resp_cmnd_done()
                  end
                  
                  def send_cmd(cmd, idx, payload, payload_json)
                      nextion.sendnx(payload)
                      tasmota.resp_cmnd_done()
                  end
                  
                  def send_cmd2(cmd, idx, payload, payload_json)
                      nextion.send(payload)
                      tasmota.resp_cmnd_done()
                  end
                  
                  tasmota.add_cmd('Nextion', send_cmd)
                  tasmota.add_cmd('CustomSend', send_cmd2)
                  tasmota.add_cmd('FlashNextion', flash_nextion)
                  tasmota.add_cmd('FlashNextionAdv', flash_nextion_adv)
                  
                  14.12.2024, 18:20:28.835	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online display firmware version => 53
                  14.12.2024, 18:20:28.852	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"nlui_driver_version":"9"}
                  14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current tasmota firmware version => 14.3.0
                  14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online berry driver version => 9
                  14.12.2024, 18:20:28.882	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current berry driver version => 9
                  14.12.2024, 18:20:28.926	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: hidden Cards disabled
                  
                  
                  K T 4 Replies Last reply
                  0
                  • K Kerschte_de

                    @tt-tom
                    Hallo Tom. Vielen Dank, dass Du Dich der Sache so schnell annimmst. Ich bin gerade auch nochmal das Video von Matthias durchgegangen, ob ich irgendwas entdecke ... habe einige Datenpunkte auch nochmal exakt nach seinem Video angelegt und dann im Script hinterlegt. Leider weiter ohne Erfolg.

                    14.12.2024, 18:20:28.125	[info ]: javascript.0 (363) Compiling TypeScript source script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT
                    14.12.2024, 18:20:28.391	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: source code did not change, using cached compilation result...
                    14.12.2024, 18:20:28.456	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: --- start of NsPanelTs: 0_userdata.0.NSPanel.1. ---
                    14.12.2024, 18:20:28.459	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: setObjects enabled - create Alias Channels possible
                    14.12.2024, 18:20:28.460	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: weather alias for accuweather.0. already exists
                    14.12.2024, 18:20:28.464	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: registered 41 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                    14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Desired TFT Firmware: 53 / v4.4.0
                    14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Installed TFT Firmware: 53 / v4.4.0
                    14.12.2024, 18:20:28.720	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Debug mode activated
                    14.12.2024, 18:20:28.788	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Tasmota Buzzer disabled
                    14.12.2024, 18:20:28.800	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: NaN W
                    14.12.2024, 18:20:28.801	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                    14.12.2024, 18:20:28.809	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting tasmota firmware version
                    14.12.2024, 18:20:28.810	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting current berry driver version
                    14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                    14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online berry driver version
                    14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online TFT version
                    14.12.2024, 18:20:28.813	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online firmware version
                    14.12.2024, 18:20:28.828	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: import adbase as ad
                    
                    from luibackend.config import LuiBackendConfig
                    from luibackend.controller import LuiController
                    from luibackend.mqtt import LuiMqttListener, LuiMqttSender
                    from luibackend.updater import Updater
                    
                    import apis
                    import json
                    from typing import Literal
                    
                    class NsPanelLovelaceUIManager(ad.ADBase):
                    
                        def initialize(self):
                            self.adapi = self.get_ad_api()
                            self.adapi.log('Starting')
                            apis.ad_api = self.adapi
                            apis.ha_api   = self.get_plugin_api("HASS")
                            apis.mqtt_api = self.get_plugin_api("MQTT")
                    
                            cfg = self._cfg = LuiBackendConfig(apis.ha_api, self.args["config"])
                    
                            use_api = cfg.get("use_api") == True
                    
                            topic_send = cfg.get("panelSendTopic")
                            topic_recv = cfg.get("panelRecvTopic")
                            api_panel_name = cfg.get("panelName")
                            api_device_id = cfg.get("panelDeviceId")
                            quiet = cfg.get("quiet")
                    
                            mqttsender = self._mqttsender = LuiMqttSender(apis.ha_api, use_api, topic_send, api_panel_name, quiet)
                    
                            self._controller = LuiController(cfg, mqttsender.send_mqtt_msg)
                            
                            desired_tasmota_driver_version   = 8
                            desired_display_firmware_version = 53
                            version     = "v4.3.3"
                            
                            model       = cfg.get("model")
                            if model == "us-l":
                                desired_display_firmware_url = cfg._config.get("displayURL-US-L", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft")
                            elif model == "us-p":
                                desired_display_firmware_url = cfg._config.get("displayURL-US-P", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft")
                            else:
                                desired_display_firmware_url = cfg._config.get("displayURL-EU",   f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft")
                            desired_tasmota_driver_url       = cfg._config.get("berryURL",         "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be")
                    
                            mode = cfg.get("updateMode")
                            updater = Updater(self.adapi.log, mqttsender, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
                            
                            # Request Tasmota Driver Version
                            updater.request_berry_driver_version()
                    
                            LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, self._controller, updater)
                    
                            self.adapi.log(f'Started ({version})')
                            
                        #
                        # helpers
                        #
                        
                        def show_card(self, card_key: str) -> None:
                            """Used to show card on panel"""
                            
                            msg = json.dumps({"CustomRecv":f"event,buttonPress2,navigate.{card_key},button"})
                            topic = self._cfg.get("panelRecvTopic")
                            self._mqttsender.send_mqtt_msg(msg, topic)
                            
                        def navigate(self, direction: Literal['up', 'prev', 'next']) -> None:
                            """Used to navigate different directions on the panel"""
                            
                            msg = json.dumps({"CustomRecv":f"event,buttonPress2,nav{direction.title()},button"})
                            topic = self._cfg.get("panelRecvTopic")
                            self._mqttsender.send_mqtt_msg(msg, topic)
                            
                        @property
                        def current_card(self) -> str:
                            """Used to get the panel's current card"""
                            
                            return self._controller.current_card.key
                    
                    14.12.2024, 18:20:28.832	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: # Sonoff NSPanel Tasmota Lovelace UI Berry Driver (Extended Flashing to faster speeds; improved Error Handling)| code by joBr99
                    # based on;
                    # Sonoff NSPanel Tasmota (Nextion with Flashing) driver | code by peepshow-21
                    # based on;
                    # Sonoff NSPanel Tasmota driver v0.47 | code by blakadder and s-hadinger
                    
                    # Example Flash
                    # FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft
                    # FlashNextion http://nspanel.pky.eu/lui.tft
                    
                    class Nextion : Driver
                    
                        static header = bytes('55BB')
                    
                        static flash_block_size = 4096
                    
                        var flash_mode
                        var flash_start_millis
                        var flash_size
                        var flash_written
                        var flash_buff
                        var flash_offset
                        var flash_proto_version
                        var flash_proto_baud
                        var awaiting_offset
                        var tcp
                        var ser
                        var last_per
                        var url
                    
                        def split_55(b)
                          var ret = []
                          var s = size(b)   
                          var i = s-2   # start from last-1
                          while i > 0
                            if b[i] == 0x55 && b[i+1] == 0xBB           
                              ret.push(b[i..s-1]) # push last msg to list
                              b = b[(0..i-1)]   # write the rest back to b
                            end
                            i -= 1
                          end
                          ret.push(b)
                          return ret
                        end
                    
                        def crc16(data, poly)
                          if !poly  poly = 0xA001 end
                          # CRC-16 MODBUS HASHING ALGORITHM
                          var crc = 0xFFFF
                          for i:0..size(data)-1
                            crc = crc ^ data[i]
                            for j:0..7
                              if crc & 1
                                crc = (crc >> 1) ^ poly
                              else
                                crc = crc >> 1
                              end
                            end
                          end
                          return crc
                        end
                    
                        # encode using custom protocol 55 BB [payload length] [payload length] [payload] [crc] [crc]
                        def encode(payload)
                          var b = bytes()
                          b += self.header
                          b.add(size(payload), 2)   # add size as 2 bytes, little endian
                          b += bytes().fromstring(payload)
                          var msg_crc = self.crc16(b)
                          b.add(msg_crc, 2)       # crc 2 bytes, little endian
                          return b
                        end
                    
                        def encodenx(payload)
                            var b = bytes().fromstring(payload)
                            b += bytes('FFFFFF')
                            return b
                        end
                    
                        def sendnx(payload)
                            import string
                            var payload_bin = self.encodenx(payload)
                            self.ser.write(payload_bin)
                            log(string.format("NXP: Nextion command sent = %s",str(payload_bin)), 3)       
                        end
                    
                        def send(payload)
                            var payload_bin = self.encode(payload)
                            if self.flash_mode==1
                                log("NXP: skipped command becuase still flashing", 3)
                            else 
                                self.ser.write(payload_bin)
                                log("NXP: payload sent = " + str(payload_bin), 3)
                            end
                        end
                    
                        def write_to_nextion(b)
                            self.ser.write(b)
                        end
                    
                        def screeninit()
                            log("NXP: Screen Initialized")
                            self.sendnx("recmod=1")        
                        end
                    
                        def write_block()
                            
                            import string
                            log("FLH: Read block",3)
                            while size(self.flash_buff)<self.flash_block_size && self.tcp.connected()
                                if self.tcp.available()>0
                                    self.flash_buff += self.tcp.readbytes(4096)
                                else
                                    tasmota.delay(50)
                                    log("FLH: Wait for available...",3)
                                end
                            end
                            log("FLH: Buff size "+str(size(self.flash_buff)),3)
                            var to_write
                            if size(self.flash_buff)>self.flash_block_size
                                to_write = self.flash_buff[0..self.flash_block_size-1]
                                self.flash_buff = self.flash_buff[self.flash_block_size..]
                            else
                                to_write = self.flash_buff
                                self.flash_buff = bytes()
                            end
                            log("FLH: Writing "+str(size(to_write)),3)
                            var per = (self.flash_written*100)/self.flash_size
                            if (self.last_per!=per) 
                                self.last_per = per
                                tasmota.publish_result(string.format("{\"Flashing\":{\"complete\": %d, \"time_elapsed\": %d}}",per , (tasmota.millis()-self.flash_start_millis)/1000), "RESULT") 
                            end
                            if size(to_write)>0
                                self.flash_written += size(to_write)
                                self.ser.write(to_write)
                            end
                            log("FLH: Total "+str(self.flash_written),3)
                            if (self.flash_written==self.flash_size)
                                log("FLH: Flashing complete - Time elapsed: %d", (tasmota.millis()-self.flash_start_millis)/1000)
                                self.flash_mode = 0
                                self.ser.deinit()
                                self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                            end
                    
                        end
                    
                        def every_100ms()
                            import string
                            if self.ser.available() > 0
                                var msg = self.ser.read()
                                if size(msg) > 0
                                    log(string.format("NXP: Received Raw = %s",str(msg)), 3)
                                    if (self.flash_mode==1)
                                        var strv = msg[0..-4].asstring()
                                        if string.find(strv,"comok 2")>=0
                                            tasmota.delay(50)
                                            log("FLH: Send (High Speed) flash start")
                                            self.flash_start_millis = tasmota.millis()
                                            #self.sendnx(string.format("whmi-wris %d,115200,res0",self.flash_size))
                                            if self.flash_proto_version == 0
                                                self.sendnx(string.format("whmi-wri %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                            else
                                                self.sendnx(string.format("whmi-wris %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                            end
                                            if self.flash_proto_baud != 115200
                                                tasmota.delay(50)
                                                self.ser.deinit()
                                                self.ser = serial(17, 16, self.flash_proto_baud, serial.SERIAL_8N1)
                                            end
                                        elif size(msg)==1 && msg[0]==0x08
                                            log("FLH: Waiting offset...",3)
                                            self.awaiting_offset = 1
                                        elif size(msg)==4 && self.awaiting_offset==1
                                            self.awaiting_offset = 0
                                            self.flash_offset = msg.get(0,4)
                                            log("FLH: Flash offset marker "+str(self.flash_offset),3)
                                            if self.flash_offset != 0
                                                self.open_url_at(self.url, self.flash_offset)
                                                self.flash_written = self.flash_offset
                                            end
                                            self.write_block()
                                        elif size(msg)==1 && msg[0]==0x05
                                            self.write_block()
                                        else
                                            log("FLH: Something has gone wrong flashing display firmware ["+str(msg)+"]",2)
                                        end
                                    else
                                        var msg_list = self.split_55(msg)
                                        for i:0..size(msg_list)-1
                                            msg = msg_list[i]
                                            if size(msg) > 0
                                                if msg == bytes('000000FFFFFF88FFFFFF')
                                                    self.screeninit()
                                                elif size(msg)>=2 && msg[0]==0x55 && msg[1]==0xBB
                                                    var jm = string.format("{\"CustomRecv\":\"%s\"}",msg[4..-3].asstring())
                                                    tasmota.publish_result(jm, "RESULT")        
                                                elif msg[0]==0x07 && size(msg)==1 # BELL/Buzzer
                                                    tasmota.cmd("buzzer 1,1")
                                                else
                                                    var jm = string.format("{\"nextion\":\"%s\"}",str(msg[0..-4]))
                                                    tasmota.publish_result(jm, "RESULT")        
                                                end
                                            end       
                                        end
                                    end
                                end
                            end
                        end      
                    
                        def begin_nextion_flash()
                            self.flash_written = 0
                            self.awaiting_offset = 0
                            self.flash_offset = 0
                            self.sendnx('DRAKJHSUYDGBNCJHGJKSHBDN')
                            self.sendnx('recmod=0')
                            self.sendnx('recmod=0')
                            self.flash_mode = 1
                            self.sendnx("connect")        
                        end
                        
                        def open_url_at(url, pos)
                            self.url = url
                            import string
                            var host
                            var port
                            var s1 = string.split(url,7)[1]
                            var i = string.find(s1,":")
                            var sa
                            if i<0
                                port = 80
                                i = string.find(s1,"/")
                                sa = string.split(s1,i)
                                host = sa[0]
                            else
                                sa = string.split(s1,i)
                                host = sa[0]
                                s1 = string.split(sa[1],1)[1]
                                i = string.find(s1,"/")
                                sa = string.split(s1,i)
                                port = int(sa[0])
                            end
                            var get = sa[1]
                            log(string.format("FLH: host: %s, port: %s, get: %s",host,port,get))
                            self.tcp = tcpclient()
                            self.tcp.connect(host,port)
                            log("FLH: Connected:"+str(self.tcp.connected()),3)
                            var get_req = "GET "+get+" HTTP/1.0\r\n"
                            get_req += string.format("Range: bytes=%d-\r\n", pos)
                            get_req += string.format("HOST: %s:%s\r\n\r\n",host,port)
                            self.tcp.write(get_req)
                            var a = self.tcp.available()
                            i = 1
                            while a==0 && i<5
                              tasmota.delay(100*i)
                              tasmota.yield() 
                              i += 1
                              log("FLH: Retry "+str(i),3)
                              a = self.tcp.available()
                            end
                            if a==0
                                log("FLH: Nothing available to read!",3)
                                return
                            end
                            var b = self.tcp.readbytes()
                            i = 0
                            var end_headers = false;
                            var headers
                            while i<size(b) && headers==nil
                                if b[i..(i+3)]==bytes().fromstring("\r\n\r\n") 
                                    headers = b[0..(i+3)].asstring()
                                    self.flash_buff = b[(i+4)..]
                                else
                                    i += 1
                                end
                            end
                            #print(headers)
                            # check http respose for code 200/206
                            if string.find(headers,"200 OK")>0 || string.find(headers,"206 Partial Content")>0
                                log("FLH: HTTP Respose is 200 OK or 206 Partial Content",3)
                            else
                                log("FLH: HTTP Respose is not 200 OK or 206 Partial Content",3)
                                print(headers)
                                return -1
                            end
                            # only set flash size if pos is zero
                            if pos == 0
                                # check http respose for content-length
                                var tag = "Content-Length: "
                                i = string.find(headers,tag)
                                if (i>0) 
                                    var i2 = string.find(headers,"\r\n",i)
                                    var s = headers[i+size(tag)..i2-1]
                                    self.flash_size=int(s)
                                end
                                log("FLH: Flash file size: "+str(self.flash_size),3)
                            end
                    
                        end
                    
                        def flash_nextion(url)
                            self.flash_size = 0
                            var res = self.open_url_at(url, 0)
                            if res != -1
                                self.begin_nextion_flash()
                            end
                        end
                    
                        def init()
                            log("NXP: Initializing Driver")
                            self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                            self.flash_mode = 0
                            self.flash_proto_version = 1
                            self.flash_proto_baud = 921600
                        end
                    
                    end
                    
                    var nextion = Nextion()
                    
                    tasmota.add_driver(nextion)
                    
                    def get_current_version(cmd, idx, payload, payload_json)
                        import string
                        var version_of_this_script = 9
                        var jm = string.format("{\"nlui_driver_version\":\"%s\"}", version_of_this_script)
                        tasmota.publish_result(jm, "RESULT")
                    end
                    
                    tasmota.add_cmd('GetDriverVersion', get_current_version)
                    
                    def update_berry_driver(cmd, idx, payload, payload_json)
                        def task()
                            import path
                            import string
                    		if string.find(payload, ".tapp") > 0
                    		    print("tapp in URL; will do .tapp update and migration if necessary")
                    			
                    			if path.exists("autoexec.be")
                    			    print("autoexec.be found; will check for migration")
                    				var autoexecfile = open('autoexec.be')
                    				var line = autoexecfile.readline()
                    				autoexecfile.close()
                    				if string.find(line, "NSPanel Tasmota Lovelace UI Berry Driver") > 0
                    			        print("found lovelace berry driver, going to delete autoexec.be and .bec")
                    					path.remove("autoexec.be")
                    					path.remove("autoexec.bec")
                    				end
                    			end
                    			
                    			var r = tasmota.urlfetch(payload, "nsp-lovelace-driver.tapp")
                                if r < 0
                                    print("Update failed")
                                else
                                    tasmota.cmd("Restart 1")
                                end
                    			
                    		elif string.find(payload, ".be") > 0
                    		    print("be in URL; will do .be update")
                    			if path.exists("nsp-lovelace-driver.tapp")
                    			    print("Error: there is the tapp version of the berry driver installed; cannot do .be update.")
                    			else
                                    var cl = webclient()
                                    cl.begin(payload)
                                    var r = cl.GET()
                                    if r == 200
                                        print("Sucessfully downloaded nspanel-lovelace-ui berry driver")
                                    else
                                        print("Error while downloading nspanel-lovelace-ui berry driver")
                                    end
                                    r = cl.write_file("autoexec.be")
                                    if r < 0
                                        print("Error while writeing nspanel-lovelace-ui berry driver")
                                    else
                                        print("Sucessfully written nspanel-lovelace-ui berry driver")
                                        tasmota.cmd("Restart 1")
                                    end
                    			end
                    		else
                    			print("invalid url filetype")
                    		end
                    		
                    		
                    		
                            if path.exists("nsp-lovelace-driver.tapp")
                                var r = string.find(payload, ".tapp")
                                if r < 0
                                    print("URL doesn't contain .tapp skipping update")
                                else
                    
                                end
                            else
                                var r = string.find(payload, ".be")
                                if r < 0
                                    print("URL doesn't contain .be skipping update")
                                else
                            
                                end                
                            end
                        end
                        tasmota.set_timer(0,task)
                        tasmota.resp_cmnd_done()
                    end
                    
                    tasmota.add_cmd('UpdateDriverVersion', update_berry_driver)
                    
                    def flash_nextion(cmd, idx, payload, payload_json)
                        def task()
                        nextion.flash_proto_version = 1
                        nextion.flash_proto_baud = 921600
                            nextion.flash_nextion(payload)
                        end
                        tasmota.set_timer(0,task)
                        tasmota.resp_cmnd_done()
                    end
                    
                    def flash_nextion_adv(cmd, idx, payload, payload_json)
                        def task()        
                            if idx==0
                                nextion.flash_proto_version = 1
                                nextion.flash_proto_baud = 921600
                            elif idx==1
                                nextion.flash_proto_version = 0
                                nextion.flash_proto_baud = 921600
                            elif idx==2
                                nextion.flash_proto_version = 1
                                nextion.flash_proto_baud = 115200
                            elif idx==3
                                nextion.flash_proto_version = 0
                                nextion.flash_proto_baud = 115200
                            elif idx==4
                                nextion.flash_proto_version = 1
                                nextion.flash_proto_baud = 256000
                            elif idx==5
                                nextion.flash_proto_version = 0
                                nextion.flash_proto_baud = 256000
                            elif idx==6
                                nextion.ser.deinit()
                                nextion.ser = serial(17, 16, 9600, serial.SERIAL_8N1)
                                nextion.flash_proto_version = 0
                                nextion.flash_proto_baud = 921600
                            else
                                nextion.flash_proto_version = 0
                                nextion.flash_proto_baud = 115200
                            end
                            
                            nextion.flash_nextion(payload)
                        end
                        tasmota.set_timer(0,task)
                        tasmota.resp_cmnd_done()
                    end
                    
                    def send_cmd(cmd, idx, payload, payload_json)
                        nextion.sendnx(payload)
                        tasmota.resp_cmnd_done()
                    end
                    
                    def send_cmd2(cmd, idx, payload, payload_json)
                        nextion.send(payload)
                        tasmota.resp_cmnd_done()
                    end
                    
                    tasmota.add_cmd('Nextion', send_cmd)
                    tasmota.add_cmd('CustomSend', send_cmd2)
                    tasmota.add_cmd('FlashNextion', flash_nextion)
                    tasmota.add_cmd('FlashNextionAdv', flash_nextion_adv)
                    
                    14.12.2024, 18:20:28.835	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online display firmware version => 53
                    14.12.2024, 18:20:28.852	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"nlui_driver_version":"9"}
                    14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current tasmota firmware version => 14.3.0
                    14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online berry driver version => 9
                    14.12.2024, 18:20:28.882	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current berry driver version => 9
                    14.12.2024, 18:20:28.926	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: hidden Cards disabled
                    
                    
                    K Offline
                    K Offline
                    Kerschte_de
                    wrote on last edited by
                    #6646

                    @kerschte_de

                    14.12.2024, 18:20:29.007	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/149090497","assets_url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/149090497/assets","upload_url":"https://uploads.github.com/repos/joBr99/nspanel-lovelace-ui/releases/149090497/assets{?name,label}","html_url":"https://github.com/joBr99/nspanel-lovelace-ui/releases/tag/v4.4.0","id":149090497,"author":{"login":"joBr99","id":29555657,"node_id":"MDQ6VXNlcjI5NTU1NjU3","avatar_url":"https://avatars.githubusercontent.com/u/29555657?v=4","gravatar_id":"","url":"https://api.github.com/users/joBr99","html_url":"https://github.com/joBr99","followers_url":"https://api.github.com/users/joBr99/followers","following_url":"https://api.github.com/users/joBr99/following{/other_user}","gists_url":"https://api.github.com/users/joBr99/gists{/gist_id}","starred_url":"https://api.github.com/users/joBr99/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joBr99/subscriptions","organizations_url":"https://api.github.com/users/joBr99/orgs","repos_url":"https://api.github.com/users/joBr99/repos","events_url":"https://api.github.com/users/joBr99/events{/privacy}","received_events_url":"https://api.github.com/users/joBr99/received_events","type":"User","user_view_type":"public","site_admin":false},"node_id":"RE_kwDOGo1zRM4I4vDB","tag_name":"v4.4.0","target_commitish":"main","name":"v4.4.0 - Update for HA 2024.04","draft":false,"prerelease":false,"created_at":"2024-03-30T11:18:31Z","published_at":"2024-03-30T12:26:37Z","assets":[],"tarball_url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/tarball/v4.4.0","zipball_url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/zipball/v4.4.0","body":"## Besides the Update of the App in HACS you need to do the following things:\r\n\r\n🔄 **Restart the AppDaemon Container**\r\n\r\n**Add the following workaround to your Home Assistant configuration.yaml**\r\n\r\nhttps://docs.nspanel.pky.eu/stable/prepare_ha/#workaround-for-homeassistant-202404\r\n\r\n🔄 **Restart Home Assistant**\r\n\r\n## New Features:\r\n\r\n- **Implemented changes to work with upcoming Homeassistant Version 2024.04 @joBr99**\r\n","mentions_count":1}
                    14.12.2024, 18:20:29.052	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online TFT firmware version => 4.4.0
                    14.12.2024, 18:20:29.083	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"url":"https://api.github.com/repos/arendst/Tasmota/releases/190153880","assets_url":"https://api.github.com/repos/arendst/Tasmota/releases/190153880/assets","upload_url":"https://uploads.github.com/repos/arendst/Tasmota/releases/190153880/assets{?name,label}","html_url":"https://github.com/arendst/Tasmota/releases/tag/v14.4.0","id":190153880,"author":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"node_id":"RE_kwDOBMkSUM4LVYSY","tag_name":"v14.4.0","target_commitish":"master","name":"Tasmota v14.4.0 Rudolph","draft":false,"prerelease":false,"created_at":"2024-12-11T09:17:21Z","published_at":"2024-12-11T09:35:47Z","assets":[{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594561","id":212594561,"node_id":"RA_kwDOBMkSUM4Mq--B","name":"map_all.zip","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/zip","state":"uploaded","size":50218975,"download_count":20,"created_at":"2024-12-11T09:35:49Z","updated_at":"2024-12-11T09:35:50Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/map_all.zip"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594403","id":212594403,"node_id":"RA_kwDOBMkSUM4Mq-7j","name":"tasmota-4M.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":739968,"download_count":41,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-4M.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594404","id":212594404,"node_id":"RA_kwDOBMkSUM4Mq-7k","name":"tasmota-4M.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":518013,"download_count":42,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-4M.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594417","id":212594417,"node_id":"RA_kwDOBMkSUM4Mq-7x","name":"tasmota-AD.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669280,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-AD.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594409","id":212594409,"node_id":"RA_kwDOBMkSUM4Mq-7p","name":"tasmota-AD.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469581,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-AD.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594407","id":212594407,"node_id":"RA_kwDOBMkSUM4Mq-7n","name":"tasmota-AF.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":668704,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-AF.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594405","id":212594405,"node_id":"RA_kwDOBMkSUM4Mq-7l","name":"tasmota-AF.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469296,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-AF.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594412","id":212594412,"node_id":"RA_kwDOBMkSUM4Mq-7s","name":"tasmota-BG.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":674672,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-BG.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594421","id":212594421,"node_id":"RA_kwDOBMkSUM4Mq-71","name":"tasmota-BG.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":470721,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-BG.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594406","id":212594406,"node_id":"RA_kwDOBMkSUM4Mq-7m","name":"tasmota-BR.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669520,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-BR.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594411","id":212594411,"node_id":"RA_kwDOBMkSUM4Mq-7r","name":"tasmota-BR.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469616,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-BR.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594410","id":212594410,"node_id":"RA_kwDOBMkSUM4Mq-7q","name":"tasmota-CN.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":668096,"download_count":37,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-CN.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594415","id":212594415,"node_id":"RA_kwDOBMkSUM4Mq-7v","name":"tasmota-CN.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469483,"download_count":34,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-CN.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594425","id":212594425,"node_id":"RA_kwDOBMkSUM4Mq-75","name":"tasmota-CZ.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669248,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-CZ.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594414","id":212594414,"node_id":"RA_kwDOBMkSUM4Mq-7u","name":"tasmota-CZ.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469625,"download_count":35,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-CZ.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594419","id":212594419,"node_id":"RA_kwDOBMkSUM4Mq-7z","name":"tasmota-DE.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":668576,"download_count":84,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-DE.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594418","id":212594418,"node_id":"RA_kwDOBMkSUM4Mq-7y","name":"tasmota-DE.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469239,"download_count":66,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-DE.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594408","id":212594408,"node_id":"RA_kwDOBMkSUM4Mq-7o","name":"tasmota-display.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":626128,"download_count":36,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-display.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594413","id":212594413,"node_id":"RA_kwDOBMkSUM4Mq-7t","name":"tasmota-display.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":430756,"download_count":40,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-display.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594427","id":212594427,"node_id":"RA_kwDOBMkSUM4Mq-77","name":"tasmota-ES.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669424,"download_count":34,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-ES.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594416","id":212594416,"node_id":"RA_kwDOBMkSUM4Mq-7w","name":"tasmota-ES.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469393,"download_count":34,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-ES.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594454","id":212594454,"node_id":"RA_kwDOBMkSUM4Mq-8W","name":"tasmota-FR.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669648,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-FR.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594422","id":212594422,"node_id":"RA_kwDOBMkSUM4Mq-72","name":"tasmota-FR.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469519,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-FR.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594436","id":212594436,"node_id":"RA_kwDOBMkSUM4Mq-8E","name":"tasmota-FY.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":668944,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-FY.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594434","id":212594434,"node_id":"RA_kwDOBMkSUM4Mq-8C","name":"tasmota-FY.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469568,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-FY.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594420","id":212594420,"node_id":"RA_kwDOBMkSUM4Mq-70","name":"tasmota-GR.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":672832,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-GR.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594423","id":212594423,"node_id":"RA_kwDOBMkSUM4Mq-73","name":"tasmota-GR.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":470557,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-GR.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594437","id":212594437,"node_id":"RA_kwDOBMkSUM4Mq-8F","name":"tasmota-HE.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":670192,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-HE.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594431","id":212594431,"node_id":"RA_kwDOBMkSUM4Mq-7_","name":"tasmota-HE.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469550,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-HE.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594438","id":212594438,"node_id":"RA_kwDOBMkSUM4Mq-8G","name":"tasmota-HU.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669552,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-HU.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594426","id":212594426,"node_id":"RA_kwDOBMkSUM4Mq-76","name":"tasmota-HU.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469699,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-HU.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594430","id":212594430,"node_id":"RA_kwDOBMkSUM4Mq-7-","name":"tasmota-ir.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":681296,"download_count":36,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-ir.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594443","id":212594443,"node_id":"RA_kwDOBMkSUM4Mq-8L","name":"tasmota-ir.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":458199,"download_count":40,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-ir.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594428","id":212594428,"node_id":"RA_kwDOBMkSUM4Mq-78","name":"tasmota-IT.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669680,"download_count":34,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-IT.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594432","id":212594432,"node_id":"RA_kwDOBMkSUM4Mq-8A","name":"tasmota-IT.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469256,"download_count":34,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-IT.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594439","id":212594439,"node_id":"RA_kwDOBMkSUM4Mq-8H","name":"tasmota-knx.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":664736,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-knx.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594424","id":212594424,"node_id":"RA_kwDOBMkSUM4Mq-74","name":"tasmota-knx.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":462131,"download_count":36,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-knx.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594442","id":212594442,"node_id":"RA_kwDOBMkSUM4Mq-8K","name":"tasmota-KO.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669168,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-KO.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594457","id":212594457,"node_id":"RA_kwDOBMkSUM4Mq-8Z","name":"tasmota-KO.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469713,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-KO.bin.gz"},
                    
                    1 Reply Last reply
                    0
                    • K Kerschte_de

                      @tt-tom
                      Hallo Tom. Vielen Dank, dass Du Dich der Sache so schnell annimmst. Ich bin gerade auch nochmal das Video von Matthias durchgegangen, ob ich irgendwas entdecke ... habe einige Datenpunkte auch nochmal exakt nach seinem Video angelegt und dann im Script hinterlegt. Leider weiter ohne Erfolg.

                      14.12.2024, 18:20:28.125	[info ]: javascript.0 (363) Compiling TypeScript source script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT
                      14.12.2024, 18:20:28.391	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: source code did not change, using cached compilation result...
                      14.12.2024, 18:20:28.456	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: --- start of NsPanelTs: 0_userdata.0.NSPanel.1. ---
                      14.12.2024, 18:20:28.459	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: setObjects enabled - create Alias Channels possible
                      14.12.2024, 18:20:28.460	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: weather alias for accuweather.0. already exists
                      14.12.2024, 18:20:28.464	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: registered 41 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                      14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Desired TFT Firmware: 53 / v4.4.0
                      14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Installed TFT Firmware: 53 / v4.4.0
                      14.12.2024, 18:20:28.720	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Debug mode activated
                      14.12.2024, 18:20:28.788	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Tasmota Buzzer disabled
                      14.12.2024, 18:20:28.800	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: NaN W
                      14.12.2024, 18:20:28.801	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                      14.12.2024, 18:20:28.809	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting tasmota firmware version
                      14.12.2024, 18:20:28.810	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting current berry driver version
                      14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                      14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online berry driver version
                      14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online TFT version
                      14.12.2024, 18:20:28.813	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online firmware version
                      14.12.2024, 18:20:28.828	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: import adbase as ad
                      
                      from luibackend.config import LuiBackendConfig
                      from luibackend.controller import LuiController
                      from luibackend.mqtt import LuiMqttListener, LuiMqttSender
                      from luibackend.updater import Updater
                      
                      import apis
                      import json
                      from typing import Literal
                      
                      class NsPanelLovelaceUIManager(ad.ADBase):
                      
                          def initialize(self):
                              self.adapi = self.get_ad_api()
                              self.adapi.log('Starting')
                              apis.ad_api = self.adapi
                              apis.ha_api   = self.get_plugin_api("HASS")
                              apis.mqtt_api = self.get_plugin_api("MQTT")
                      
                              cfg = self._cfg = LuiBackendConfig(apis.ha_api, self.args["config"])
                      
                              use_api = cfg.get("use_api") == True
                      
                              topic_send = cfg.get("panelSendTopic")
                              topic_recv = cfg.get("panelRecvTopic")
                              api_panel_name = cfg.get("panelName")
                              api_device_id = cfg.get("panelDeviceId")
                              quiet = cfg.get("quiet")
                      
                              mqttsender = self._mqttsender = LuiMqttSender(apis.ha_api, use_api, topic_send, api_panel_name, quiet)
                      
                              self._controller = LuiController(cfg, mqttsender.send_mqtt_msg)
                              
                              desired_tasmota_driver_version   = 8
                              desired_display_firmware_version = 53
                              version     = "v4.3.3"
                              
                              model       = cfg.get("model")
                              if model == "us-l":
                                  desired_display_firmware_url = cfg._config.get("displayURL-US-L", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft")
                              elif model == "us-p":
                                  desired_display_firmware_url = cfg._config.get("displayURL-US-P", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft")
                              else:
                                  desired_display_firmware_url = cfg._config.get("displayURL-EU",   f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft")
                              desired_tasmota_driver_url       = cfg._config.get("berryURL",         "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be")
                      
                              mode = cfg.get("updateMode")
                              updater = Updater(self.adapi.log, mqttsender, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
                              
                              # Request Tasmota Driver Version
                              updater.request_berry_driver_version()
                      
                              LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, self._controller, updater)
                      
                              self.adapi.log(f'Started ({version})')
                              
                          #
                          # helpers
                          #
                          
                          def show_card(self, card_key: str) -> None:
                              """Used to show card on panel"""
                              
                              msg = json.dumps({"CustomRecv":f"event,buttonPress2,navigate.{card_key},button"})
                              topic = self._cfg.get("panelRecvTopic")
                              self._mqttsender.send_mqtt_msg(msg, topic)
                              
                          def navigate(self, direction: Literal['up', 'prev', 'next']) -> None:
                              """Used to navigate different directions on the panel"""
                              
                              msg = json.dumps({"CustomRecv":f"event,buttonPress2,nav{direction.title()},button"})
                              topic = self._cfg.get("panelRecvTopic")
                              self._mqttsender.send_mqtt_msg(msg, topic)
                              
                          @property
                          def current_card(self) -> str:
                              """Used to get the panel's current card"""
                              
                              return self._controller.current_card.key
                      
                      14.12.2024, 18:20:28.832	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: # Sonoff NSPanel Tasmota Lovelace UI Berry Driver (Extended Flashing to faster speeds; improved Error Handling)| code by joBr99
                      # based on;
                      # Sonoff NSPanel Tasmota (Nextion with Flashing) driver | code by peepshow-21
                      # based on;
                      # Sonoff NSPanel Tasmota driver v0.47 | code by blakadder and s-hadinger
                      
                      # Example Flash
                      # FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft
                      # FlashNextion http://nspanel.pky.eu/lui.tft
                      
                      class Nextion : Driver
                      
                          static header = bytes('55BB')
                      
                          static flash_block_size = 4096
                      
                          var flash_mode
                          var flash_start_millis
                          var flash_size
                          var flash_written
                          var flash_buff
                          var flash_offset
                          var flash_proto_version
                          var flash_proto_baud
                          var awaiting_offset
                          var tcp
                          var ser
                          var last_per
                          var url
                      
                          def split_55(b)
                            var ret = []
                            var s = size(b)   
                            var i = s-2   # start from last-1
                            while i > 0
                              if b[i] == 0x55 && b[i+1] == 0xBB           
                                ret.push(b[i..s-1]) # push last msg to list
                                b = b[(0..i-1)]   # write the rest back to b
                              end
                              i -= 1
                            end
                            ret.push(b)
                            return ret
                          end
                      
                          def crc16(data, poly)
                            if !poly  poly = 0xA001 end
                            # CRC-16 MODBUS HASHING ALGORITHM
                            var crc = 0xFFFF
                            for i:0..size(data)-1
                              crc = crc ^ data[i]
                              for j:0..7
                                if crc & 1
                                  crc = (crc >> 1) ^ poly
                                else
                                  crc = crc >> 1
                                end
                              end
                            end
                            return crc
                          end
                      
                          # encode using custom protocol 55 BB [payload length] [payload length] [payload] [crc] [crc]
                          def encode(payload)
                            var b = bytes()
                            b += self.header
                            b.add(size(payload), 2)   # add size as 2 bytes, little endian
                            b += bytes().fromstring(payload)
                            var msg_crc = self.crc16(b)
                            b.add(msg_crc, 2)       # crc 2 bytes, little endian
                            return b
                          end
                      
                          def encodenx(payload)
                              var b = bytes().fromstring(payload)
                              b += bytes('FFFFFF')
                              return b
                          end
                      
                          def sendnx(payload)
                              import string
                              var payload_bin = self.encodenx(payload)
                              self.ser.write(payload_bin)
                              log(string.format("NXP: Nextion command sent = %s",str(payload_bin)), 3)       
                          end
                      
                          def send(payload)
                              var payload_bin = self.encode(payload)
                              if self.flash_mode==1
                                  log("NXP: skipped command becuase still flashing", 3)
                              else 
                                  self.ser.write(payload_bin)
                                  log("NXP: payload sent = " + str(payload_bin), 3)
                              end
                          end
                      
                          def write_to_nextion(b)
                              self.ser.write(b)
                          end
                      
                          def screeninit()
                              log("NXP: Screen Initialized")
                              self.sendnx("recmod=1")        
                          end
                      
                          def write_block()
                              
                              import string
                              log("FLH: Read block",3)
                              while size(self.flash_buff)<self.flash_block_size && self.tcp.connected()
                                  if self.tcp.available()>0
                                      self.flash_buff += self.tcp.readbytes(4096)
                                  else
                                      tasmota.delay(50)
                                      log("FLH: Wait for available...",3)
                                  end
                              end
                              log("FLH: Buff size "+str(size(self.flash_buff)),3)
                              var to_write
                              if size(self.flash_buff)>self.flash_block_size
                                  to_write = self.flash_buff[0..self.flash_block_size-1]
                                  self.flash_buff = self.flash_buff[self.flash_block_size..]
                              else
                                  to_write = self.flash_buff
                                  self.flash_buff = bytes()
                              end
                              log("FLH: Writing "+str(size(to_write)),3)
                              var per = (self.flash_written*100)/self.flash_size
                              if (self.last_per!=per) 
                                  self.last_per = per
                                  tasmota.publish_result(string.format("{\"Flashing\":{\"complete\": %d, \"time_elapsed\": %d}}",per , (tasmota.millis()-self.flash_start_millis)/1000), "RESULT") 
                              end
                              if size(to_write)>0
                                  self.flash_written += size(to_write)
                                  self.ser.write(to_write)
                              end
                              log("FLH: Total "+str(self.flash_written),3)
                              if (self.flash_written==self.flash_size)
                                  log("FLH: Flashing complete - Time elapsed: %d", (tasmota.millis()-self.flash_start_millis)/1000)
                                  self.flash_mode = 0
                                  self.ser.deinit()
                                  self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                              end
                      
                          end
                      
                          def every_100ms()
                              import string
                              if self.ser.available() > 0
                                  var msg = self.ser.read()
                                  if size(msg) > 0
                                      log(string.format("NXP: Received Raw = %s",str(msg)), 3)
                                      if (self.flash_mode==1)
                                          var strv = msg[0..-4].asstring()
                                          if string.find(strv,"comok 2")>=0
                                              tasmota.delay(50)
                                              log("FLH: Send (High Speed) flash start")
                                              self.flash_start_millis = tasmota.millis()
                                              #self.sendnx(string.format("whmi-wris %d,115200,res0",self.flash_size))
                                              if self.flash_proto_version == 0
                                                  self.sendnx(string.format("whmi-wri %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                              else
                                                  self.sendnx(string.format("whmi-wris %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                              end
                                              if self.flash_proto_baud != 115200
                                                  tasmota.delay(50)
                                                  self.ser.deinit()
                                                  self.ser = serial(17, 16, self.flash_proto_baud, serial.SERIAL_8N1)
                                              end
                                          elif size(msg)==1 && msg[0]==0x08
                                              log("FLH: Waiting offset...",3)
                                              self.awaiting_offset = 1
                                          elif size(msg)==4 && self.awaiting_offset==1
                                              self.awaiting_offset = 0
                                              self.flash_offset = msg.get(0,4)
                                              log("FLH: Flash offset marker "+str(self.flash_offset),3)
                                              if self.flash_offset != 0
                                                  self.open_url_at(self.url, self.flash_offset)
                                                  self.flash_written = self.flash_offset
                                              end
                                              self.write_block()
                                          elif size(msg)==1 && msg[0]==0x05
                                              self.write_block()
                                          else
                                              log("FLH: Something has gone wrong flashing display firmware ["+str(msg)+"]",2)
                                          end
                                      else
                                          var msg_list = self.split_55(msg)
                                          for i:0..size(msg_list)-1
                                              msg = msg_list[i]
                                              if size(msg) > 0
                                                  if msg == bytes('000000FFFFFF88FFFFFF')
                                                      self.screeninit()
                                                  elif size(msg)>=2 && msg[0]==0x55 && msg[1]==0xBB
                                                      var jm = string.format("{\"CustomRecv\":\"%s\"}",msg[4..-3].asstring())
                                                      tasmota.publish_result(jm, "RESULT")        
                                                  elif msg[0]==0x07 && size(msg)==1 # BELL/Buzzer
                                                      tasmota.cmd("buzzer 1,1")
                                                  else
                                                      var jm = string.format("{\"nextion\":\"%s\"}",str(msg[0..-4]))
                                                      tasmota.publish_result(jm, "RESULT")        
                                                  end
                                              end       
                                          end
                                      end
                                  end
                              end
                          end      
                      
                          def begin_nextion_flash()
                              self.flash_written = 0
                              self.awaiting_offset = 0
                              self.flash_offset = 0
                              self.sendnx('DRAKJHSUYDGBNCJHGJKSHBDN')
                              self.sendnx('recmod=0')
                              self.sendnx('recmod=0')
                              self.flash_mode = 1
                              self.sendnx("connect")        
                          end
                          
                          def open_url_at(url, pos)
                              self.url = url
                              import string
                              var host
                              var port
                              var s1 = string.split(url,7)[1]
                              var i = string.find(s1,":")
                              var sa
                              if i<0
                                  port = 80
                                  i = string.find(s1,"/")
                                  sa = string.split(s1,i)
                                  host = sa[0]
                              else
                                  sa = string.split(s1,i)
                                  host = sa[0]
                                  s1 = string.split(sa[1],1)[1]
                                  i = string.find(s1,"/")
                                  sa = string.split(s1,i)
                                  port = int(sa[0])
                              end
                              var get = sa[1]
                              log(string.format("FLH: host: %s, port: %s, get: %s",host,port,get))
                              self.tcp = tcpclient()
                              self.tcp.connect(host,port)
                              log("FLH: Connected:"+str(self.tcp.connected()),3)
                              var get_req = "GET "+get+" HTTP/1.0\r\n"
                              get_req += string.format("Range: bytes=%d-\r\n", pos)
                              get_req += string.format("HOST: %s:%s\r\n\r\n",host,port)
                              self.tcp.write(get_req)
                              var a = self.tcp.available()
                              i = 1
                              while a==0 && i<5
                                tasmota.delay(100*i)
                                tasmota.yield() 
                                i += 1
                                log("FLH: Retry "+str(i),3)
                                a = self.tcp.available()
                              end
                              if a==0
                                  log("FLH: Nothing available to read!",3)
                                  return
                              end
                              var b = self.tcp.readbytes()
                              i = 0
                              var end_headers = false;
                              var headers
                              while i<size(b) && headers==nil
                                  if b[i..(i+3)]==bytes().fromstring("\r\n\r\n") 
                                      headers = b[0..(i+3)].asstring()
                                      self.flash_buff = b[(i+4)..]
                                  else
                                      i += 1
                                  end
                              end
                              #print(headers)
                              # check http respose for code 200/206
                              if string.find(headers,"200 OK")>0 || string.find(headers,"206 Partial Content")>0
                                  log("FLH: HTTP Respose is 200 OK or 206 Partial Content",3)
                              else
                                  log("FLH: HTTP Respose is not 200 OK or 206 Partial Content",3)
                                  print(headers)
                                  return -1
                              end
                              # only set flash size if pos is zero
                              if pos == 0
                                  # check http respose for content-length
                                  var tag = "Content-Length: "
                                  i = string.find(headers,tag)
                                  if (i>0) 
                                      var i2 = string.find(headers,"\r\n",i)
                                      var s = headers[i+size(tag)..i2-1]
                                      self.flash_size=int(s)
                                  end
                                  log("FLH: Flash file size: "+str(self.flash_size),3)
                              end
                      
                          end
                      
                          def flash_nextion(url)
                              self.flash_size = 0
                              var res = self.open_url_at(url, 0)
                              if res != -1
                                  self.begin_nextion_flash()
                              end
                          end
                      
                          def init()
                              log("NXP: Initializing Driver")
                              self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                              self.flash_mode = 0
                              self.flash_proto_version = 1
                              self.flash_proto_baud = 921600
                          end
                      
                      end
                      
                      var nextion = Nextion()
                      
                      tasmota.add_driver(nextion)
                      
                      def get_current_version(cmd, idx, payload, payload_json)
                          import string
                          var version_of_this_script = 9
                          var jm = string.format("{\"nlui_driver_version\":\"%s\"}", version_of_this_script)
                          tasmota.publish_result(jm, "RESULT")
                      end
                      
                      tasmota.add_cmd('GetDriverVersion', get_current_version)
                      
                      def update_berry_driver(cmd, idx, payload, payload_json)
                          def task()
                              import path
                              import string
                      		if string.find(payload, ".tapp") > 0
                      		    print("tapp in URL; will do .tapp update and migration if necessary")
                      			
                      			if path.exists("autoexec.be")
                      			    print("autoexec.be found; will check for migration")
                      				var autoexecfile = open('autoexec.be')
                      				var line = autoexecfile.readline()
                      				autoexecfile.close()
                      				if string.find(line, "NSPanel Tasmota Lovelace UI Berry Driver") > 0
                      			        print("found lovelace berry driver, going to delete autoexec.be and .bec")
                      					path.remove("autoexec.be")
                      					path.remove("autoexec.bec")
                      				end
                      			end
                      			
                      			var r = tasmota.urlfetch(payload, "nsp-lovelace-driver.tapp")
                                  if r < 0
                                      print("Update failed")
                                  else
                                      tasmota.cmd("Restart 1")
                                  end
                      			
                      		elif string.find(payload, ".be") > 0
                      		    print("be in URL; will do .be update")
                      			if path.exists("nsp-lovelace-driver.tapp")
                      			    print("Error: there is the tapp version of the berry driver installed; cannot do .be update.")
                      			else
                                      var cl = webclient()
                                      cl.begin(payload)
                                      var r = cl.GET()
                                      if r == 200
                                          print("Sucessfully downloaded nspanel-lovelace-ui berry driver")
                                      else
                                          print("Error while downloading nspanel-lovelace-ui berry driver")
                                      end
                                      r = cl.write_file("autoexec.be")
                                      if r < 0
                                          print("Error while writeing nspanel-lovelace-ui berry driver")
                                      else
                                          print("Sucessfully written nspanel-lovelace-ui berry driver")
                                          tasmota.cmd("Restart 1")
                                      end
                      			end
                      		else
                      			print("invalid url filetype")
                      		end
                      		
                      		
                      		
                              if path.exists("nsp-lovelace-driver.tapp")
                                  var r = string.find(payload, ".tapp")
                                  if r < 0
                                      print("URL doesn't contain .tapp skipping update")
                                  else
                      
                                  end
                              else
                                  var r = string.find(payload, ".be")
                                  if r < 0
                                      print("URL doesn't contain .be skipping update")
                                  else
                              
                                  end                
                              end
                          end
                          tasmota.set_timer(0,task)
                          tasmota.resp_cmnd_done()
                      end
                      
                      tasmota.add_cmd('UpdateDriverVersion', update_berry_driver)
                      
                      def flash_nextion(cmd, idx, payload, payload_json)
                          def task()
                          nextion.flash_proto_version = 1
                          nextion.flash_proto_baud = 921600
                              nextion.flash_nextion(payload)
                          end
                          tasmota.set_timer(0,task)
                          tasmota.resp_cmnd_done()
                      end
                      
                      def flash_nextion_adv(cmd, idx, payload, payload_json)
                          def task()        
                              if idx==0
                                  nextion.flash_proto_version = 1
                                  nextion.flash_proto_baud = 921600
                              elif idx==1
                                  nextion.flash_proto_version = 0
                                  nextion.flash_proto_baud = 921600
                              elif idx==2
                                  nextion.flash_proto_version = 1
                                  nextion.flash_proto_baud = 115200
                              elif idx==3
                                  nextion.flash_proto_version = 0
                                  nextion.flash_proto_baud = 115200
                              elif idx==4
                                  nextion.flash_proto_version = 1
                                  nextion.flash_proto_baud = 256000
                              elif idx==5
                                  nextion.flash_proto_version = 0
                                  nextion.flash_proto_baud = 256000
                              elif idx==6
                                  nextion.ser.deinit()
                                  nextion.ser = serial(17, 16, 9600, serial.SERIAL_8N1)
                                  nextion.flash_proto_version = 0
                                  nextion.flash_proto_baud = 921600
                              else
                                  nextion.flash_proto_version = 0
                                  nextion.flash_proto_baud = 115200
                              end
                              
                              nextion.flash_nextion(payload)
                          end
                          tasmota.set_timer(0,task)
                          tasmota.resp_cmnd_done()
                      end
                      
                      def send_cmd(cmd, idx, payload, payload_json)
                          nextion.sendnx(payload)
                          tasmota.resp_cmnd_done()
                      end
                      
                      def send_cmd2(cmd, idx, payload, payload_json)
                          nextion.send(payload)
                          tasmota.resp_cmnd_done()
                      end
                      
                      tasmota.add_cmd('Nextion', send_cmd)
                      tasmota.add_cmd('CustomSend', send_cmd2)
                      tasmota.add_cmd('FlashNextion', flash_nextion)
                      tasmota.add_cmd('FlashNextionAdv', flash_nextion_adv)
                      
                      14.12.2024, 18:20:28.835	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online display firmware version => 53
                      14.12.2024, 18:20:28.852	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"nlui_driver_version":"9"}
                      14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current tasmota firmware version => 14.3.0
                      14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online berry driver version => 9
                      14.12.2024, 18:20:28.882	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current berry driver version => 9
                      14.12.2024, 18:20:28.926	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: hidden Cards disabled
                      
                      
                      K Offline
                      K Offline
                      Kerschte_de
                      wrote on last edited by
                      #6647

                      @kerschte_de

                      {"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594433","id":212594433,"node_id":"RA_kwDOBMkSUM4Mq-8B","name":"tasmota-lite.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":520208,"download_count":62,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-lite.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594444","id":212594444,"node_id":"RA_kwDOBMkSUM4Mq-8M","name":"tasmota-lite.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":364868,"download_count":59,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-lite.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594429","id":212594429,"node_id":"RA_kwDOBMkSUM4Mq-79","name":"tasmota-minimal.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":374432,"download_count":108,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-minimal.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594435","id":212594435,"node_id":"RA_kwDOBMkSUM4Mq-8D","name":"tasmota-minimal.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":264238,"download_count":113,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-minimal.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594456","id":212594456,"node_id":"RA_kwDOBMkSUM4Mq-8Y","name":"tasmota-NL.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669024,"download_count":34,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-NL.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594441","id":212594441,"node_id":"RA_kwDOBMkSUM4Mq-8J","name":"tasmota-NL.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469232,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-NL.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594448","id":212594448,"node_id":"RA_kwDOBMkSUM4Mq-8Q","name":"tasmota-PL.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669680,"download_count":36,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-PL.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594440","id":212594440,"node_id":"RA_kwDOBMkSUM4Mq-8I","name":"tasmota-PL.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469819,"download_count":34,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-PL.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594445","id":212594445,"node_id":"RA_kwDOBMkSUM4Mq-8N","name":"tasmota-PT.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669744,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-PT.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594463","id":212594463,"node_id":"RA_kwDOBMkSUM4Mq-8f","name":"tasmota-PT.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469557,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-PT.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594447","id":212594447,"node_id":"RA_kwDOBMkSUM4Mq-8P","name":"tasmota-RO.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669024,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-RO.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594458","id":212594458,"node_id":"RA_kwDOBMkSUM4Mq-8a","name":"tasmota-RO.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469329,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-RO.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594449","id":212594449,"node_id":"RA_kwDOBMkSUM4Mq-8R","name":"tasmota-RU.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":673744,"download_count":35,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-RU.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594462","id":212594462,"node_id":"RA_kwDOBMkSUM4Mq-8e","name":"tasmota-RU.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":470822,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-RU.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594469","id":212594469,"node_id":"RA_kwDOBMkSUM4Mq-8l","name":"tasmota-SE.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669104,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-SE.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594451","id":212594451,"node_id":"RA_kwDOBMkSUM4Mq-8T","name":"tasmota-SE.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469458,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-SE.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594455","id":212594455,"node_id":"RA_kwDOBMkSUM4Mq-8X","name":"tasmota-sensors.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":736896,"download_count":48,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-sensors.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594446","id":212594446,"node_id":"RA_kwDOBMkSUM4Mq-8O","name":"tasmota-sensors.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":510956,"download_count":53,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-sensors.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594472","id":212594472,"node_id":"RA_kwDOBMkSUM4Mq-8o","name":"tasmota-SK.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669328,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-SK.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594467","id":212594467,"node_id":"RA_kwDOBMkSUM4Mq-8j","name":"tasmota-SK.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469668,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-SK.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594452","id":212594452,"node_id":"RA_kwDOBMkSUM4Mq-8U","name":"tasmota-TR.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":669248,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-TR.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594466","id":212594466,"node_id":"RA_kwDOBMkSUM4Mq-8i","name":"tasmota-TR.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469588,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-TR.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594453","id":212594453,"node_id":"RA_kwDOBMkSUM4Mq-8V","name":"tasmota-TW.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":668704,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-TW.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594450","id":212594450,"node_id":"RA_kwDOBMkSUM4Mq-8S","name":"tasmota-TW.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469967,"download_count":32,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-TW.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594461","id":212594461,"node_id":"RA_kwDOBMkSUM4Mq-8d","name":"tasmota-UK.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":673856,"download_count":38,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-UK.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594459","id":212594459,"node_id":"RA_kwDOBMkSUM4Mq-8b","name":"tasmota-UK.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":470776,"download_count":34,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-UK.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594474","id":212594474,"node_id":"RA_kwDOBMkSUM4Mq-8q","name":"tasmota-VN.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":670496,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-VN.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594464","id":212594464,"node_id":"RA_kwDOBMkSUM4Mq-8g","name":"tasmota-VN.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":469736,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-VN.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594468","id":212594468,"node_id":"RA_kwDOBMkSUM4Mq-8k","name":"tasmota-zbbridge.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":765456,"download_count":37,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-zbbridge.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594475","id":212594475,"node_id":"RA_kwDOBMkSUM4Mq-8r","name":"tasmota-zbbridge.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":527313,"download_count":40,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-zbbridge.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594460","id":212594460,"node_id":"RA_kwDOBMkSUM4Mq-8c","name":"tasmota-zigbee.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":857760,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-zigbee.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594465","id":212594465,"node_id":"RA_kwDOBMkSUM4Mq-8h","name":"tasmota-zigbee.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":590540,"download_count":36,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota-zigbee.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594482","id":212594482,"node_id":"RA_kwDOBMkSUM4Mq-8y","name":"tasmota.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":668064,"download_count":84,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594479","id":212594479,"node_id":"RA_kwDOBMkSUM4Mq-8v","name":"tasmota.bin.gz","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/gzip","state":"uploaded","size":468540,"download_count":83,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota.bin.gz"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594473","id":212594473,"node_id":"RA_kwDOBMkSUM4Mq-8p","name":"tasmota32-AD.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":2066048,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota32-AD.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594471","id":212594471,"node_id":"RA_kwDOBMkSUM4Mq-8n","name":"tasmota32-AD.factory.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":2983552,"download_count":34,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota32-AD.factory.bin"},{"url":"https://api.github.com/repos/arendst/Tasmota/releases/assets/212594478","id":212594478,"node_id":"RA_kwDOBMkSUM4Mq-8u","name":"tasmota32-AF.bin","label":"","uploader":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"content_type":"application/octet-stream","state":"uploaded","size":2065568,"download_count":33,"created_at":"2024-12-11T09:35:48Z","updated_at":"2024-12-11T09:35:49Z","browser_download_url":"https://github.com/arendst/Tasmota/releases/download/v14.4.0/tasmota32-AF.bin"},
                      
                      1 Reply Last reply
                      0
                      • K Kerschte_de

                        @tt-tom
                        Hallo Tom. Vielen Dank, dass Du Dich der Sache so schnell annimmst. Ich bin gerade auch nochmal das Video von Matthias durchgegangen, ob ich irgendwas entdecke ... habe einige Datenpunkte auch nochmal exakt nach seinem Video angelegt und dann im Script hinterlegt. Leider weiter ohne Erfolg.

                        14.12.2024, 18:20:28.125	[info ]: javascript.0 (363) Compiling TypeScript source script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT
                        14.12.2024, 18:20:28.391	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: source code did not change, using cached compilation result...
                        14.12.2024, 18:20:28.456	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: --- start of NsPanelTs: 0_userdata.0.NSPanel.1. ---
                        14.12.2024, 18:20:28.459	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: setObjects enabled - create Alias Channels possible
                        14.12.2024, 18:20:28.460	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: weather alias for accuweather.0. already exists
                        14.12.2024, 18:20:28.464	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: registered 41 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                        14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Desired TFT Firmware: 53 / v4.4.0
                        14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Installed TFT Firmware: 53 / v4.4.0
                        14.12.2024, 18:20:28.720	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Debug mode activated
                        14.12.2024, 18:20:28.788	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Tasmota Buzzer disabled
                        14.12.2024, 18:20:28.800	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: NaN W
                        14.12.2024, 18:20:28.801	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                        14.12.2024, 18:20:28.809	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting tasmota firmware version
                        14.12.2024, 18:20:28.810	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting current berry driver version
                        14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                        14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online berry driver version
                        14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online TFT version
                        14.12.2024, 18:20:28.813	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online firmware version
                        14.12.2024, 18:20:28.828	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: import adbase as ad
                        
                        from luibackend.config import LuiBackendConfig
                        from luibackend.controller import LuiController
                        from luibackend.mqtt import LuiMqttListener, LuiMqttSender
                        from luibackend.updater import Updater
                        
                        import apis
                        import json
                        from typing import Literal
                        
                        class NsPanelLovelaceUIManager(ad.ADBase):
                        
                            def initialize(self):
                                self.adapi = self.get_ad_api()
                                self.adapi.log('Starting')
                                apis.ad_api = self.adapi
                                apis.ha_api   = self.get_plugin_api("HASS")
                                apis.mqtt_api = self.get_plugin_api("MQTT")
                        
                                cfg = self._cfg = LuiBackendConfig(apis.ha_api, self.args["config"])
                        
                                use_api = cfg.get("use_api") == True
                        
                                topic_send = cfg.get("panelSendTopic")
                                topic_recv = cfg.get("panelRecvTopic")
                                api_panel_name = cfg.get("panelName")
                                api_device_id = cfg.get("panelDeviceId")
                                quiet = cfg.get("quiet")
                        
                                mqttsender = self._mqttsender = LuiMqttSender(apis.ha_api, use_api, topic_send, api_panel_name, quiet)
                        
                                self._controller = LuiController(cfg, mqttsender.send_mqtt_msg)
                                
                                desired_tasmota_driver_version   = 8
                                desired_display_firmware_version = 53
                                version     = "v4.3.3"
                                
                                model       = cfg.get("model")
                                if model == "us-l":
                                    desired_display_firmware_url = cfg._config.get("displayURL-US-L", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft")
                                elif model == "us-p":
                                    desired_display_firmware_url = cfg._config.get("displayURL-US-P", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft")
                                else:
                                    desired_display_firmware_url = cfg._config.get("displayURL-EU",   f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft")
                                desired_tasmota_driver_url       = cfg._config.get("berryURL",         "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be")
                        
                                mode = cfg.get("updateMode")
                                updater = Updater(self.adapi.log, mqttsender, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
                                
                                # Request Tasmota Driver Version
                                updater.request_berry_driver_version()
                        
                                LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, self._controller, updater)
                        
                                self.adapi.log(f'Started ({version})')
                                
                            #
                            # helpers
                            #
                            
                            def show_card(self, card_key: str) -> None:
                                """Used to show card on panel"""
                                
                                msg = json.dumps({"CustomRecv":f"event,buttonPress2,navigate.{card_key},button"})
                                topic = self._cfg.get("panelRecvTopic")
                                self._mqttsender.send_mqtt_msg(msg, topic)
                                
                            def navigate(self, direction: Literal['up', 'prev', 'next']) -> None:
                                """Used to navigate different directions on the panel"""
                                
                                msg = json.dumps({"CustomRecv":f"event,buttonPress2,nav{direction.title()},button"})
                                topic = self._cfg.get("panelRecvTopic")
                                self._mqttsender.send_mqtt_msg(msg, topic)
                                
                            @property
                            def current_card(self) -> str:
                                """Used to get the panel's current card"""
                                
                                return self._controller.current_card.key
                        
                        14.12.2024, 18:20:28.832	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: # Sonoff NSPanel Tasmota Lovelace UI Berry Driver (Extended Flashing to faster speeds; improved Error Handling)| code by joBr99
                        # based on;
                        # Sonoff NSPanel Tasmota (Nextion with Flashing) driver | code by peepshow-21
                        # based on;
                        # Sonoff NSPanel Tasmota driver v0.47 | code by blakadder and s-hadinger
                        
                        # Example Flash
                        # FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft
                        # FlashNextion http://nspanel.pky.eu/lui.tft
                        
                        class Nextion : Driver
                        
                            static header = bytes('55BB')
                        
                            static flash_block_size = 4096
                        
                            var flash_mode
                            var flash_start_millis
                            var flash_size
                            var flash_written
                            var flash_buff
                            var flash_offset
                            var flash_proto_version
                            var flash_proto_baud
                            var awaiting_offset
                            var tcp
                            var ser
                            var last_per
                            var url
                        
                            def split_55(b)
                              var ret = []
                              var s = size(b)   
                              var i = s-2   # start from last-1
                              while i > 0
                                if b[i] == 0x55 && b[i+1] == 0xBB           
                                  ret.push(b[i..s-1]) # push last msg to list
                                  b = b[(0..i-1)]   # write the rest back to b
                                end
                                i -= 1
                              end
                              ret.push(b)
                              return ret
                            end
                        
                            def crc16(data, poly)
                              if !poly  poly = 0xA001 end
                              # CRC-16 MODBUS HASHING ALGORITHM
                              var crc = 0xFFFF
                              for i:0..size(data)-1
                                crc = crc ^ data[i]
                                for j:0..7
                                  if crc & 1
                                    crc = (crc >> 1) ^ poly
                                  else
                                    crc = crc >> 1
                                  end
                                end
                              end
                              return crc
                            end
                        
                            # encode using custom protocol 55 BB [payload length] [payload length] [payload] [crc] [crc]
                            def encode(payload)
                              var b = bytes()
                              b += self.header
                              b.add(size(payload), 2)   # add size as 2 bytes, little endian
                              b += bytes().fromstring(payload)
                              var msg_crc = self.crc16(b)
                              b.add(msg_crc, 2)       # crc 2 bytes, little endian
                              return b
                            end
                        
                            def encodenx(payload)
                                var b = bytes().fromstring(payload)
                                b += bytes('FFFFFF')
                                return b
                            end
                        
                            def sendnx(payload)
                                import string
                                var payload_bin = self.encodenx(payload)
                                self.ser.write(payload_bin)
                                log(string.format("NXP: Nextion command sent = %s",str(payload_bin)), 3)       
                            end
                        
                            def send(payload)
                                var payload_bin = self.encode(payload)
                                if self.flash_mode==1
                                    log("NXP: skipped command becuase still flashing", 3)
                                else 
                                    self.ser.write(payload_bin)
                                    log("NXP: payload sent = " + str(payload_bin), 3)
                                end
                            end
                        
                            def write_to_nextion(b)
                                self.ser.write(b)
                            end
                        
                            def screeninit()
                                log("NXP: Screen Initialized")
                                self.sendnx("recmod=1")        
                            end
                        
                            def write_block()
                                
                                import string
                                log("FLH: Read block",3)
                                while size(self.flash_buff)<self.flash_block_size && self.tcp.connected()
                                    if self.tcp.available()>0
                                        self.flash_buff += self.tcp.readbytes(4096)
                                    else
                                        tasmota.delay(50)
                                        log("FLH: Wait for available...",3)
                                    end
                                end
                                log("FLH: Buff size "+str(size(self.flash_buff)),3)
                                var to_write
                                if size(self.flash_buff)>self.flash_block_size
                                    to_write = self.flash_buff[0..self.flash_block_size-1]
                                    self.flash_buff = self.flash_buff[self.flash_block_size..]
                                else
                                    to_write = self.flash_buff
                                    self.flash_buff = bytes()
                                end
                                log("FLH: Writing "+str(size(to_write)),3)
                                var per = (self.flash_written*100)/self.flash_size
                                if (self.last_per!=per) 
                                    self.last_per = per
                                    tasmota.publish_result(string.format("{\"Flashing\":{\"complete\": %d, \"time_elapsed\": %d}}",per , (tasmota.millis()-self.flash_start_millis)/1000), "RESULT") 
                                end
                                if size(to_write)>0
                                    self.flash_written += size(to_write)
                                    self.ser.write(to_write)
                                end
                                log("FLH: Total "+str(self.flash_written),3)
                                if (self.flash_written==self.flash_size)
                                    log("FLH: Flashing complete - Time elapsed: %d", (tasmota.millis()-self.flash_start_millis)/1000)
                                    self.flash_mode = 0
                                    self.ser.deinit()
                                    self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                                end
                        
                            end
                        
                            def every_100ms()
                                import string
                                if self.ser.available() > 0
                                    var msg = self.ser.read()
                                    if size(msg) > 0
                                        log(string.format("NXP: Received Raw = %s",str(msg)), 3)
                                        if (self.flash_mode==1)
                                            var strv = msg[0..-4].asstring()
                                            if string.find(strv,"comok 2")>=0
                                                tasmota.delay(50)
                                                log("FLH: Send (High Speed) flash start")
                                                self.flash_start_millis = tasmota.millis()
                                                #self.sendnx(string.format("whmi-wris %d,115200,res0",self.flash_size))
                                                if self.flash_proto_version == 0
                                                    self.sendnx(string.format("whmi-wri %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                                else
                                                    self.sendnx(string.format("whmi-wris %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                                end
                                                if self.flash_proto_baud != 115200
                                                    tasmota.delay(50)
                                                    self.ser.deinit()
                                                    self.ser = serial(17, 16, self.flash_proto_baud, serial.SERIAL_8N1)
                                                end
                                            elif size(msg)==1 && msg[0]==0x08
                                                log("FLH: Waiting offset...",3)
                                                self.awaiting_offset = 1
                                            elif size(msg)==4 && self.awaiting_offset==1
                                                self.awaiting_offset = 0
                                                self.flash_offset = msg.get(0,4)
                                                log("FLH: Flash offset marker "+str(self.flash_offset),3)
                                                if self.flash_offset != 0
                                                    self.open_url_at(self.url, self.flash_offset)
                                                    self.flash_written = self.flash_offset
                                                end
                                                self.write_block()
                                            elif size(msg)==1 && msg[0]==0x05
                                                self.write_block()
                                            else
                                                log("FLH: Something has gone wrong flashing display firmware ["+str(msg)+"]",2)
                                            end
                                        else
                                            var msg_list = self.split_55(msg)
                                            for i:0..size(msg_list)-1
                                                msg = msg_list[i]
                                                if size(msg) > 0
                                                    if msg == bytes('000000FFFFFF88FFFFFF')
                                                        self.screeninit()
                                                    elif size(msg)>=2 && msg[0]==0x55 && msg[1]==0xBB
                                                        var jm = string.format("{\"CustomRecv\":\"%s\"}",msg[4..-3].asstring())
                                                        tasmota.publish_result(jm, "RESULT")        
                                                    elif msg[0]==0x07 && size(msg)==1 # BELL/Buzzer
                                                        tasmota.cmd("buzzer 1,1")
                                                    else
                                                        var jm = string.format("{\"nextion\":\"%s\"}",str(msg[0..-4]))
                                                        tasmota.publish_result(jm, "RESULT")        
                                                    end
                                                end       
                                            end
                                        end
                                    end
                                end
                            end      
                        
                            def begin_nextion_flash()
                                self.flash_written = 0
                                self.awaiting_offset = 0
                                self.flash_offset = 0
                                self.sendnx('DRAKJHSUYDGBNCJHGJKSHBDN')
                                self.sendnx('recmod=0')
                                self.sendnx('recmod=0')
                                self.flash_mode = 1
                                self.sendnx("connect")        
                            end
                            
                            def open_url_at(url, pos)
                                self.url = url
                                import string
                                var host
                                var port
                                var s1 = string.split(url,7)[1]
                                var i = string.find(s1,":")
                                var sa
                                if i<0
                                    port = 80
                                    i = string.find(s1,"/")
                                    sa = string.split(s1,i)
                                    host = sa[0]
                                else
                                    sa = string.split(s1,i)
                                    host = sa[0]
                                    s1 = string.split(sa[1],1)[1]
                                    i = string.find(s1,"/")
                                    sa = string.split(s1,i)
                                    port = int(sa[0])
                                end
                                var get = sa[1]
                                log(string.format("FLH: host: %s, port: %s, get: %s",host,port,get))
                                self.tcp = tcpclient()
                                self.tcp.connect(host,port)
                                log("FLH: Connected:"+str(self.tcp.connected()),3)
                                var get_req = "GET "+get+" HTTP/1.0\r\n"
                                get_req += string.format("Range: bytes=%d-\r\n", pos)
                                get_req += string.format("HOST: %s:%s\r\n\r\n",host,port)
                                self.tcp.write(get_req)
                                var a = self.tcp.available()
                                i = 1
                                while a==0 && i<5
                                  tasmota.delay(100*i)
                                  tasmota.yield() 
                                  i += 1
                                  log("FLH: Retry "+str(i),3)
                                  a = self.tcp.available()
                                end
                                if a==0
                                    log("FLH: Nothing available to read!",3)
                                    return
                                end
                                var b = self.tcp.readbytes()
                                i = 0
                                var end_headers = false;
                                var headers
                                while i<size(b) && headers==nil
                                    if b[i..(i+3)]==bytes().fromstring("\r\n\r\n") 
                                        headers = b[0..(i+3)].asstring()
                                        self.flash_buff = b[(i+4)..]
                                    else
                                        i += 1
                                    end
                                end
                                #print(headers)
                                # check http respose for code 200/206
                                if string.find(headers,"200 OK")>0 || string.find(headers,"206 Partial Content")>0
                                    log("FLH: HTTP Respose is 200 OK or 206 Partial Content",3)
                                else
                                    log("FLH: HTTP Respose is not 200 OK or 206 Partial Content",3)
                                    print(headers)
                                    return -1
                                end
                                # only set flash size if pos is zero
                                if pos == 0
                                    # check http respose for content-length
                                    var tag = "Content-Length: "
                                    i = string.find(headers,tag)
                                    if (i>0) 
                                        var i2 = string.find(headers,"\r\n",i)
                                        var s = headers[i+size(tag)..i2-1]
                                        self.flash_size=int(s)
                                    end
                                    log("FLH: Flash file size: "+str(self.flash_size),3)
                                end
                        
                            end
                        
                            def flash_nextion(url)
                                self.flash_size = 0
                                var res = self.open_url_at(url, 0)
                                if res != -1
                                    self.begin_nextion_flash()
                                end
                            end
                        
                            def init()
                                log("NXP: Initializing Driver")
                                self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                                self.flash_mode = 0
                                self.flash_proto_version = 1
                                self.flash_proto_baud = 921600
                            end
                        
                        end
                        
                        var nextion = Nextion()
                        
                        tasmota.add_driver(nextion)
                        
                        def get_current_version(cmd, idx, payload, payload_json)
                            import string
                            var version_of_this_script = 9
                            var jm = string.format("{\"nlui_driver_version\":\"%s\"}", version_of_this_script)
                            tasmota.publish_result(jm, "RESULT")
                        end
                        
                        tasmota.add_cmd('GetDriverVersion', get_current_version)
                        
                        def update_berry_driver(cmd, idx, payload, payload_json)
                            def task()
                                import path
                                import string
                        		if string.find(payload, ".tapp") > 0
                        		    print("tapp in URL; will do .tapp update and migration if necessary")
                        			
                        			if path.exists("autoexec.be")
                        			    print("autoexec.be found; will check for migration")
                        				var autoexecfile = open('autoexec.be')
                        				var line = autoexecfile.readline()
                        				autoexecfile.close()
                        				if string.find(line, "NSPanel Tasmota Lovelace UI Berry Driver") > 0
                        			        print("found lovelace berry driver, going to delete autoexec.be and .bec")
                        					path.remove("autoexec.be")
                        					path.remove("autoexec.bec")
                        				end
                        			end
                        			
                        			var r = tasmota.urlfetch(payload, "nsp-lovelace-driver.tapp")
                                    if r < 0
                                        print("Update failed")
                                    else
                                        tasmota.cmd("Restart 1")
                                    end
                        			
                        		elif string.find(payload, ".be") > 0
                        		    print("be in URL; will do .be update")
                        			if path.exists("nsp-lovelace-driver.tapp")
                        			    print("Error: there is the tapp version of the berry driver installed; cannot do .be update.")
                        			else
                                        var cl = webclient()
                                        cl.begin(payload)
                                        var r = cl.GET()
                                        if r == 200
                                            print("Sucessfully downloaded nspanel-lovelace-ui berry driver")
                                        else
                                            print("Error while downloading nspanel-lovelace-ui berry driver")
                                        end
                                        r = cl.write_file("autoexec.be")
                                        if r < 0
                                            print("Error while writeing nspanel-lovelace-ui berry driver")
                                        else
                                            print("Sucessfully written nspanel-lovelace-ui berry driver")
                                            tasmota.cmd("Restart 1")
                                        end
                        			end
                        		else
                        			print("invalid url filetype")
                        		end
                        		
                        		
                        		
                                if path.exists("nsp-lovelace-driver.tapp")
                                    var r = string.find(payload, ".tapp")
                                    if r < 0
                                        print("URL doesn't contain .tapp skipping update")
                                    else
                        
                                    end
                                else
                                    var r = string.find(payload, ".be")
                                    if r < 0
                                        print("URL doesn't contain .be skipping update")
                                    else
                                
                                    end                
                                end
                            end
                            tasmota.set_timer(0,task)
                            tasmota.resp_cmnd_done()
                        end
                        
                        tasmota.add_cmd('UpdateDriverVersion', update_berry_driver)
                        
                        def flash_nextion(cmd, idx, payload, payload_json)
                            def task()
                            nextion.flash_proto_version = 1
                            nextion.flash_proto_baud = 921600
                                nextion.flash_nextion(payload)
                            end
                            tasmota.set_timer(0,task)
                            tasmota.resp_cmnd_done()
                        end
                        
                        def flash_nextion_adv(cmd, idx, payload, payload_json)
                            def task()        
                                if idx==0
                                    nextion.flash_proto_version = 1
                                    nextion.flash_proto_baud = 921600
                                elif idx==1
                                    nextion.flash_proto_version = 0
                                    nextion.flash_proto_baud = 921600
                                elif idx==2
                                    nextion.flash_proto_version = 1
                                    nextion.flash_proto_baud = 115200
                                elif idx==3
                                    nextion.flash_proto_version = 0
                                    nextion.flash_proto_baud = 115200
                                elif idx==4
                                    nextion.flash_proto_version = 1
                                    nextion.flash_proto_baud = 256000
                                elif idx==5
                                    nextion.flash_proto_version = 0
                                    nextion.flash_proto_baud = 256000
                                elif idx==6
                                    nextion.ser.deinit()
                                    nextion.ser = serial(17, 16, 9600, serial.SERIAL_8N1)
                                    nextion.flash_proto_version = 0
                                    nextion.flash_proto_baud = 921600
                                else
                                    nextion.flash_proto_version = 0
                                    nextion.flash_proto_baud = 115200
                                end
                                
                                nextion.flash_nextion(payload)
                            end
                            tasmota.set_timer(0,task)
                            tasmota.resp_cmnd_done()
                        end
                        
                        def send_cmd(cmd, idx, payload, payload_json)
                            nextion.sendnx(payload)
                            tasmota.resp_cmnd_done()
                        end
                        
                        def send_cmd2(cmd, idx, payload, payload_json)
                            nextion.send(payload)
                            tasmota.resp_cmnd_done()
                        end
                        
                        tasmota.add_cmd('Nextion', send_cmd)
                        tasmota.add_cmd('CustomSend', send_cmd2)
                        tasmota.add_cmd('FlashNextion', flash_nextion)
                        tasmota.add_cmd('FlashNextionAdv', flash_nextion_adv)
                        
                        14.12.2024, 18:20:28.835	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online display firmware version => 53
                        14.12.2024, 18:20:28.852	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"nlui_driver_version":"9"}
                        14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current tasmota firmware version => 14.3.0
                        14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online berry driver version => 9
                        14.12.2024, 18:20:28.882	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current berry driver version => 9
                        14.12.2024, 18:20:28.926	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: hidden Cards disabled
                        
                        
                        K Offline
                        K Offline
                        Kerschte_de
                        wrote on last edited by
                        #6648

                        @kerschte_de

                        da ist was durcheinandergekommen, da ich die maximale Zeichenzahl übersteige. Ich versuche es nochmal ab Zeile 572

                        javascript.0	18:20:28.125	info	Compiling TypeScript source script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT
                        javascript.0	18:20:28.391	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: source code did not change, using cached compilation result...
                        javascript.0	18:20:28.456	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: --- start of NsPanelTs: 0_userdata.0.NSPanel.1. ---
                        javascript.0	18:20:28.459	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: setObjects enabled - create Alias Channels possible
                        javascript.0	18:20:28.460	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: weather alias for accuweather.0. already exists
                        javascript.0	18:20:28.464	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: registered 41 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                        javascript.0	18:20:28.502	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Desired TFT Firmware: 53 / v4.4.0
                        javascript.0	18:20:28.502	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Installed TFT Firmware: 53 / v4.4.0
                        javascript.0	18:20:28.720	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Debug mode activated
                        javascript.0	18:20:28.788	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Tasmota Buzzer disabled
                        javascript.0	18:20:28.800	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: NaN W
                        javascript.0	18:20:28.801	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                        javascript.0	18:20:28.809	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting tasmota firmware version
                        javascript.0	18:20:28.810	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting current berry driver version
                        javascript.0	18:20:28.811	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                        javascript.0	18:20:28.811	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online berry driver version
                        javascript.0	18:20:28.811	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online TFT version
                        javascript.0	18:20:28.813	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online firmware version
                        javascript.0	18:20:28.828	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: import adbase as ad from luibackend.config import LuiBackendConfig from luibackend.controller import LuiController from luibackend.mqtt import LuiMqttListener, LuiMqttSender from luibackend.updater import Updater import apis import json from typing import Literal class NsPanelLovelaceUIManager(ad.ADBase): def initialize(self): self.adapi = self.get_ad_api() self.adapi.log('Starting') apis.ad_api = self.adapi apis.ha_api = self.get_plugin_api("HASS") apis.mqtt_api = self.get_plugin_api("MQTT") cfg = self._cfg = LuiBackendConfig(apis.ha_api, self.args["config"]) use_api = cfg.get("use_api") == True topic_send = cfg.get("panelSendTopic") topic_recv = cfg.get("panelRecvTopic") api_panel_name = cfg.get("panelName") api_device_id = cfg.get("panelDeviceId") quiet = cfg.get("quiet") mqttsender = self._mqttsender = LuiMqttSender(apis.ha_api, use_api, topic_send, api_panel_name, quiet) self._controller = LuiController(cfg, mqttsender.send_mqtt_msg) desired_tasmota_driver_version = 8 desired_display_firmware_version = 53 version = "v4.3.3" model = cfg.get("model") if model == "us-l": desired_display_firmware_url = cfg._config.get("displayURL-US-L", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft") elif model == "us-p": desired_display_firmware_url = cfg._config.get("displayURL-US-P", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft") else: desired_display_firmware_url = cfg._config.get("displayURL-EU", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft") desired_tasmota_driver_url = cfg._config.get("berryURL", "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be") mode = cfg.get("updateMode") updater = Updater(self.adapi.log, mqttsender, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url) # Request Tasmota Driver Version updater.request_berry_driver_version() LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, self._controller, updater) self.adapi.log(f'Started ({version})') # # helpers # def show_card(self, card_key: str) -> None: """Used to show card on panel""" msg = json.dumps({"CustomRecv":f"event,buttonPress2,navigate.{card_key},button"}) topic = self._cfg.get("panelRecvTopic") self._mqttsender.send_mqtt_msg(msg, topic) def navigate(self, direction: Literal['up', 'prev', 'next']) -> None: """Used to navigate different directions on the panel""" msg = json.dumps({"CustomRecv":f"event,buttonPress2,nav{direction.title()},button"}) topic = self._cfg.get("panelRecvTopic") self._mqttsender.send_mqtt_msg(msg, topic) @property def current_card(self) -> str: """Used to get the panel's current card""" return self._controller.current_card.key
                        javascript.0	18:20:28.832	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: # Sonoff NSPanel Tasmota Lovelace UI Berry Driver (Extended Flashing to faster speeds; improved Error Handling)| code by joBr99 # based on; # Sonoff NSPanel Tasmota (Nextion with Flashing) driver | code by peepshow-21 # based on; # Sonoff NSPanel Tasmota driver v0.47 | code by blakadder and s-hadinger # Example Flash # FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft # FlashNextion http://nspanel.pky.eu/lui.tft class Nextion : Driver static header = bytes('55BB') static flash_block_size = 4096 var flash_mode var flash_start_millis var flash_size var flash_written var flash_buff var flash_offset var flash_proto_version var flash_proto_baud var awaiting_offset var tcp var ser var last_per var url def split_55(b) var ret = [] var s = size(b) var i = s-2 # start from last-1 while i > 0 if b[i] == 0x55 && b[i+1] == 0xBB ret.push(b[i..s-1]) # push last msg to list b = b[(0..i-1)] # write the rest back to b end i -= 1 end ret.push(b) return ret end def crc16(data, poly) if !poly poly = 0xA001 end # CRC-16 MODBUS HASHING ALGORITHM var crc = 0xFFFF for i:0..size(data)-1 crc = crc ^ data[i] for j:0..7 if crc & 1 crc = (crc >> 1) ^ poly else crc = crc >> 1 end end end return crc end # encode using custom protocol 55 BB [payload length] [payload length] [payload] [crc] [crc] def encode(payload) var b = bytes() b += self.header b.add(size(payload), 2) # add size as 2 bytes, little endian b += bytes().fromstring(payload) var msg_crc = self.crc16(b) b.add(msg_crc, 2) # crc 2 bytes, little endian return b end def encodenx(payload) var b = bytes().fromstring(payload) b += bytes('FFFFFF') return b end def sendnx(payload) import string var payload_bin = self.encodenx(payload) self.ser.write(payload_bin) log(string.format("NXP: Nextion command sent = %s",str(payload_bin)), 3) end def send(payload) var payload_bin = self.encode(payload) if self.flash_mode==1 log("NXP: skipped command becuase still flashing", 3) else self.ser.write(payload_bin) log("NXP: payload sent = " + str(payload_bin), 3) end end def write_to_nextion(b) self.ser.write(b) end def screeninit() log("NXP: Screen Initialized") self.sendnx("recmod=1") end def write_block() import string log("FLH: Read block",3) while size(self.flash_buff)<self.flash_block_size && self.tcp.connected() if self.tcp.available()>0 self.flash_buff += self.tcp.readbytes(4096) else tasmota.delay(50) log("FLH: Wait for available...",3) end end log("FLH: Buff size "+str(size(self.flash_buff)),3) var to_write if size(self.flash_buff)>self.flash_block_size to_write = self.flash_buff[0..self.flash_block_size-1] self.flash_buff = self.flash_buff[self.flash_block_size..] else to_write = self.flash_buff self.flash_buff = bytes() end log("FLH: Writing "+str(size(to_write)),3) var per = (self.flash_written*100)/self.flash_size if (self.last_per!=per) self.last_per = per tasmota.publish_result(string.format("{\"Flashing\":{\"complete\": %d, \"time_elapsed\": %d}}",per , (tasmota.millis()-self.flash_start_millis)/1000), "RESULT") end if size(to_write)>0 self.flash_written += size(to_write) self.ser.write(to_write) end log("FLH: Total "+str(self.flash_written),3) if (self.flash_written==self.flash_size) log("FLH: Flashing complete - Time elapsed: %d", (tasmota.millis()-self.flash_start_millis)/1000) self.flash_mode = 0 self.ser.deinit() self.ser = serial(17, 16, 115200, serial.SERIAL_8N1) end end def every_100ms() import string if self.ser.available() > 0 var msg = self.ser.read() if size(msg) > 0 log(string.format("NXP: Received Raw = %s",str(msg)), 3) if (self.flash_mode==1) var strv = msg[0..-4].asstring() if string.find(strv,"comok 2")>=0 tasmota.delay(50) log("FLH: Send (High Speed) flash start") self.flash_start_millis = tasmota.millis() #self.sendnx(string.format("whmi-wris %d,115200,res0",self.flash_size)) if self.flash_proto_version == 0 self.sendnx(string.format("whmi-wri %d,%d,res0",self.flash_size,self.flash_proto_baud)) else self.sendnx(string.format("whmi-wris %d,%d,res0",self.flash_size,self.flash_proto_baud)) end if self.flash_proto_baud != 115200 tasmota.delay(50) self.ser.deinit() self.ser = serial(17, 16, self.flash_proto_baud, serial.SERIAL_8N1) end elif size(msg)==1 && msg[0]==0x08 log("FLH: Waiting offset...",3) self.awaiting_offset = 1 elif size(msg)==4 && self.awaiting_offset==1 self.awaiting_offset = 0 self.flash_offset = msg.get(0,4) log("FLH: Flash offset marker "+str(self.flash_offset),3) if self.flash_offset != 0 self.open_url_at(self.url, self.flash_offset) self.flash_written = self.flash_offset end self.write_block() elif size(msg)==1 && msg[0]==0x05 self.write_block() else log("FLH: Something has gone wrong flashing display firmware ["+str(msg)+"]",2) end else var msg_list = self.split_55(msg) for i:0..size(msg_list)-1 msg = msg_list[i] if size(msg) > 0 if msg == bytes('000000FFFFFF88FFFFFF') self.screeninit() elif size(msg)>=2 && msg[0]==0x55 && msg[1]==0xBB var jm = string.format("{\"CustomRecv\":\"%s\"}",msg[4..-3].asstring()) tasmota.publish_result(jm, "RESULT") elif msg[0]==0x07 && size(msg)==1 # BELL/Buzzer tasmota.cmd("buzzer 1,1") else var jm = string.format("{\"nextion\":\"%s\"}",str(msg[0..-4])) tasmota.publish_result(jm, "RESULT") end end end end end end end def begin_nextion_flash() self.flash_written = 0 self.awaiting_offset = 0 self.flash_offset = 0 self.sendnx('DRAKJHSUYDGBNCJHGJKSHBDN') self.sendnx('recmod=0') self.sendnx('recmod=0') self.flash_mode = 1 self.sendnx("connect") end def open_url_at(url, pos) self.url = url import string var host var port var s1 = string.split(url,7)[1] var i = string.find(s1,":") var sa if i<0 port = 80 i = string.find(s1,"/") sa = string.split(s1,i) host = sa[0] else sa = string.split(s1,i) host = sa[0] s1 = string.split(sa[1],1)[1] i = string.find(s1,"/") sa = string.split(s1,i) port = int(sa[0]) end var get = sa[1] log(string.format("FLH: host: %s, port: %s, get: %s",host,port,get)) self.tcp = tcpclient() self.tcp.connect(host,port) log("FLH: Connected:"+str(self.tcp.connected()),3) var get_req = "GET "+get+" HTTP/1.0\r\n" get_req += string.format("Range: bytes=%d-\r\n", pos) get_req += string.format("HOST: %s:%s\r\n\r\n",host,port) self.tcp.write(get_req) var a = self.tcp.available() i = 1 while a==0 && i<5 tasmota.delay(100*i) tasmota.yield() i += 1 log("FLH: Retry "+str(i),3) a = self.tcp.available() end if a==0 log("FLH: Nothing available to read!",3) return end var b = self.tcp.readbytes() i = 0 var end_headers = false; var headers while i<size(b) && headers==nil if b[i..(i+3)]==bytes().fromstring("\r\n\r\n") headers = b[0..(i+3)].asstring() self.flash_buff = b[(i+4)..] else i += 1 end end #print(headers) # check http respose for code 200/206 if string.find(headers,"200 OK")>0 || string.find(headers,"206 Partial Content")>0 log("FLH: HTTP Respose is 200 OK or 206 Partial Content",3) else log("FLH: HTTP Respose is not 200 OK or 206 Partial Content",3) print(headers) return -1 end # only set flash size if pos is zero if pos == 0 # check http respose for content-length var tag = "Content-Length: " i = string.find(headers,tag) if (i>0) var i2 = string.find(headers,"\r\n",i) var s = headers[i+size(tag)..i2-1] self.flash_size=int(s) end log("FLH: Flash file size: "+str(self.flash_size),3) end end def flash_nextion(url) self.flash_size = 0 var res = self.open_url_at(url, 0) if res != -1 self.begin_nextion_flash() end end def init() log("NXP: Initializing Driver") self.ser = serial(17, 16, 115200, serial.SERIAL_8N1) self.flash_mode = 0 self.flash_proto_version = 1 self.flash_proto_baud = 921600 end end var nextion = Nextion() tasmota.add_driver(nextion) def get_current_version(cmd, idx, payload, payload_json) import string var version_of_this_script = 9 var jm = string.format("{\"nlui_driver_version\":\"%s\"}", version_of_this_script) tasmota.publish_result(jm, "RESULT") end tasmota.add_cmd('GetDriverVersion', get_current_version) def update_berry_driver(cmd, idx, payload, payload_json) def task() import path import string if string.find(payload, ".tapp") > 0 print("tapp in URL; will do .tapp update and migration if necessary") if path.exists("autoexec.be") print("autoexec.be found; will check for migration") var autoexecfile = open('autoexec.be') var line = autoexecfile.readline() autoexecfile.close() if string.find(line, "NSPanel Tasmota Lovelace UI Berry Driver") > 0 print("found lovelace berry driver, going to delete autoexec.be and .bec") path.remove("autoexec.be") path.remove("autoexec.bec") end end var r = tasmota.urlfetch(payload, "nsp-lovelace-driver.tapp") if r < 0 print("Update failed") else tasmota.cmd("Restart 1") end elif string.find(payload, ".be") > 0 print("be in URL; will do .be update") if path.exists("nsp-lovelace-driver.tapp") print("Error: there is the tapp version of the berry driver installed; cannot do .be update.") else var cl = webclient() cl.begin(payload) var r = cl.GET() if r == 200 print("Sucessfully downloaded nspanel-lovelace-ui berry driver") else print("Error while downloading nspanel-lovelace-ui berry driver") end r = cl.write_file("autoexec.be") if r < 0 print("Error while writeing nspanel-lovelace-ui berry driver") else print("Sucessfully written nspanel-lovelace-ui berry driver") tasmota.cmd("Restart 1") end end else print("invalid url filetype") end if path.exists("nsp-lovelace-driver.tapp") var r = string.find(payload, ".tapp") if r < 0 print("URL doesn't contain .tapp skipping update") else end else var r = string.find(payload, ".be") if r < 0 print("URL doesn't contain .be skipping update") else end end end tasmota.set_timer(0,task) tasmota.resp_cmnd_done() end tasmota.add_cmd('UpdateDriverVersion', update_berry_driver) def flash_nextion(cmd, idx, payload, payload_json) def task() nextion.flash_proto_version = 1 nextion.flash_proto_baud = 921600 nextion.flash_nextion(payload) end tasmota.set_timer(0,task) tasmota.resp_cmnd_done() end def flash_nextion_adv(cmd, idx, payload, payload_json) def task() if idx==0 nextion.flash_proto_version = 1 nextion.flash_proto_baud = 921600 elif idx==1 nextion.flash_proto_version = 0 nextion.flash_proto_baud = 921600 elif idx==2 nextion.flash_proto_version = 1 nextion.flash_proto_baud = 115200 elif idx==3 nextion.flash_proto_version = 0 nextion.flash_proto_baud = 115200 elif idx==4 nextion.flash_proto_version = 1 nextion.flash_proto_baud = 256000 elif idx==5 nextion.flash_proto_version = 0 nextion.flash_proto_baud = 256000 elif idx==6 nextion.ser.deinit() nextion.ser = serial(17, 16, 9600, serial.SERIAL_8N1) nextion.flash_proto_version = 0 nextion.flash_proto_baud = 921600 else nextion.flash_proto_version = 0 nextion.flash_proto_baud = 115200 end nextion.flash_nextion(payload) end tasmota.set_timer(0,task) tasmota.resp_cmnd_done() end def send_cmd(cmd, idx, payload, payload_json) nextion.sendnx(payload) tasmota.resp_cmnd_done() end def send_cmd2(cmd, idx, payload, payload_json) nextion.send(payload) tasmota.resp_cmnd_done() end tasmota.add_cmd('Nextion', send_cmd) tasmota.add_cmd('CustomSend', send_cmd2) tasmota.add_cmd('FlashNextion', flash_nextion) tasmota.add_cmd('FlashNextionAdv', flash_nextion_adv)
                        javascript.0	18:20:28.835	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online display firmware version => 53
                        javascript.0	18:20:28.852	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"nlui_driver_version":"9"}
                        javascript.0	18:20:28.855	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current tasmota firmware version => 14.3.0
                        javascript.0	18:20:28.855	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online berry driver version => 9
                        javascript.0	18:20:28.882	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current berry driver version => 9
                        javascript.0	18:20:28.926	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: hidden Cards disabled
                        javascript.0	18:20:29.007	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/149090497","assets_url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/149090497/assets","upload_url":"https://uploads.github.com/repos/joBr99/nspanel-lovelace-ui/releases/149090497/assets{?name,label}","html_url":"https://github.com/joBr99/nspanel-lovelace-ui/releases/tag/v4.4.0","id":149090497,"author":{"login":"joBr99","id":29555657,"node_id":"MDQ6VXNlcjI5NTU1NjU3","avatar_url":"https://avatars.githubusercontent.com/u/29555657?v=4","gravatar_id":"","url":"https://api.github.com/users/joBr99","html_url":"https://github.com/joBr99","followers_url":"https://api.github.com/users/joBr99/followers","following_url":"https://api.github.com/users/joBr99/following{/other_user}","gists_url":"https://api.github.com/users/joBr99/gists{/gist_id}","starred_url":"https://api.github.com/users/joBr99/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joBr99/subscriptions","organizations_url":"https://api.github.com/users/joBr99/orgs","repos_url":"https://api.github.com/users/joBr99/repos","events_url":"https://api.github.com/users/joBr99/events{/privacy}","received_events_url":"https://api.github.com/users/joBr99/received_events","type":"User","user_view_type":"public","site_admin":false},"node_id":"RE_kwDOGo1zRM4I4vDB","tag_name":"v4.4.0","target_commitish":"main","name":"v4.4.0 - Update for HA 2024.04","draft":false,"prerelease":false,"created_at":"2024-03-30T11:18:31Z","published_at":"2024-03-30T12:26:37Z","assets":[],"tarball_url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/tarball/v4.4.0","zipball_url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/zipball/v4.4.0","body":"## Besides the Update of the App in HACS you need to do the following things:\r\n\r\n🔄 **Restart the AppDaemon Container**\r\n\r\n**Add the following workaround to your Home Assistant configuration.yaml**\r\n\r\nhttps://docs.nspanel.pky.eu/stable/prepare_ha/#workaround-for-homeassistant-202404\r\n\r\n🔄 **Restart Home Assistant**\r\n\r\n## New Features:\r\n\r\n- **Implemented changes to work with upcoming Homeassistant Version 2024.04 @joBr99**\r\n","mentions_count":1}
                        
                        T 1 Reply Last reply
                        0
                        • K Kerschte_de

                          @tt-tom
                          Hallo Tom. Vielen Dank, dass Du Dich der Sache so schnell annimmst. Ich bin gerade auch nochmal das Video von Matthias durchgegangen, ob ich irgendwas entdecke ... habe einige Datenpunkte auch nochmal exakt nach seinem Video angelegt und dann im Script hinterlegt. Leider weiter ohne Erfolg.

                          14.12.2024, 18:20:28.125	[info ]: javascript.0 (363) Compiling TypeScript source script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT
                          14.12.2024, 18:20:28.391	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: source code did not change, using cached compilation result...
                          14.12.2024, 18:20:28.456	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: --- start of NsPanelTs: 0_userdata.0.NSPanel.1. ---
                          14.12.2024, 18:20:28.459	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: setObjects enabled - create Alias Channels possible
                          14.12.2024, 18:20:28.460	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: weather alias for accuweather.0. already exists
                          14.12.2024, 18:20:28.464	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: registered 41 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                          14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Desired TFT Firmware: 53 / v4.4.0
                          14.12.2024, 18:20:28.502	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Installed TFT Firmware: 53 / v4.4.0
                          14.12.2024, 18:20:28.720	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Debug mode activated
                          14.12.2024, 18:20:28.788	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Tasmota Buzzer disabled
                          14.12.2024, 18:20:28.800	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: NaN W
                          14.12.2024, 18:20:28.801	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                          14.12.2024, 18:20:28.809	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting tasmota firmware version
                          14.12.2024, 18:20:28.810	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting current berry driver version
                          14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                          14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online berry driver version
                          14.12.2024, 18:20:28.811	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online TFT version
                          14.12.2024, 18:20:28.813	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online firmware version
                          14.12.2024, 18:20:28.828	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: import adbase as ad
                          
                          from luibackend.config import LuiBackendConfig
                          from luibackend.controller import LuiController
                          from luibackend.mqtt import LuiMqttListener, LuiMqttSender
                          from luibackend.updater import Updater
                          
                          import apis
                          import json
                          from typing import Literal
                          
                          class NsPanelLovelaceUIManager(ad.ADBase):
                          
                              def initialize(self):
                                  self.adapi = self.get_ad_api()
                                  self.adapi.log('Starting')
                                  apis.ad_api = self.adapi
                                  apis.ha_api   = self.get_plugin_api("HASS")
                                  apis.mqtt_api = self.get_plugin_api("MQTT")
                          
                                  cfg = self._cfg = LuiBackendConfig(apis.ha_api, self.args["config"])
                          
                                  use_api = cfg.get("use_api") == True
                          
                                  topic_send = cfg.get("panelSendTopic")
                                  topic_recv = cfg.get("panelRecvTopic")
                                  api_panel_name = cfg.get("panelName")
                                  api_device_id = cfg.get("panelDeviceId")
                                  quiet = cfg.get("quiet")
                          
                                  mqttsender = self._mqttsender = LuiMqttSender(apis.ha_api, use_api, topic_send, api_panel_name, quiet)
                          
                                  self._controller = LuiController(cfg, mqttsender.send_mqtt_msg)
                                  
                                  desired_tasmota_driver_version   = 8
                                  desired_display_firmware_version = 53
                                  version     = "v4.3.3"
                                  
                                  model       = cfg.get("model")
                                  if model == "us-l":
                                      desired_display_firmware_url = cfg._config.get("displayURL-US-L", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft")
                                  elif model == "us-p":
                                      desired_display_firmware_url = cfg._config.get("displayURL-US-P", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft")
                                  else:
                                      desired_display_firmware_url = cfg._config.get("displayURL-EU",   f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft")
                                  desired_tasmota_driver_url       = cfg._config.get("berryURL",         "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be")
                          
                                  mode = cfg.get("updateMode")
                                  updater = Updater(self.adapi.log, mqttsender, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
                                  
                                  # Request Tasmota Driver Version
                                  updater.request_berry_driver_version()
                          
                                  LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, self._controller, updater)
                          
                                  self.adapi.log(f'Started ({version})')
                                  
                              #
                              # helpers
                              #
                              
                              def show_card(self, card_key: str) -> None:
                                  """Used to show card on panel"""
                                  
                                  msg = json.dumps({"CustomRecv":f"event,buttonPress2,navigate.{card_key},button"})
                                  topic = self._cfg.get("panelRecvTopic")
                                  self._mqttsender.send_mqtt_msg(msg, topic)
                                  
                              def navigate(self, direction: Literal['up', 'prev', 'next']) -> None:
                                  """Used to navigate different directions on the panel"""
                                  
                                  msg = json.dumps({"CustomRecv":f"event,buttonPress2,nav{direction.title()},button"})
                                  topic = self._cfg.get("panelRecvTopic")
                                  self._mqttsender.send_mqtt_msg(msg, topic)
                                  
                              @property
                              def current_card(self) -> str:
                                  """Used to get the panel's current card"""
                                  
                                  return self._controller.current_card.key
                          
                          14.12.2024, 18:20:28.832	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: # Sonoff NSPanel Tasmota Lovelace UI Berry Driver (Extended Flashing to faster speeds; improved Error Handling)| code by joBr99
                          # based on;
                          # Sonoff NSPanel Tasmota (Nextion with Flashing) driver | code by peepshow-21
                          # based on;
                          # Sonoff NSPanel Tasmota driver v0.47 | code by blakadder and s-hadinger
                          
                          # Example Flash
                          # FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft
                          # FlashNextion http://nspanel.pky.eu/lui.tft
                          
                          class Nextion : Driver
                          
                              static header = bytes('55BB')
                          
                              static flash_block_size = 4096
                          
                              var flash_mode
                              var flash_start_millis
                              var flash_size
                              var flash_written
                              var flash_buff
                              var flash_offset
                              var flash_proto_version
                              var flash_proto_baud
                              var awaiting_offset
                              var tcp
                              var ser
                              var last_per
                              var url
                          
                              def split_55(b)
                                var ret = []
                                var s = size(b)   
                                var i = s-2   # start from last-1
                                while i > 0
                                  if b[i] == 0x55 && b[i+1] == 0xBB           
                                    ret.push(b[i..s-1]) # push last msg to list
                                    b = b[(0..i-1)]   # write the rest back to b
                                  end
                                  i -= 1
                                end
                                ret.push(b)
                                return ret
                              end
                          
                              def crc16(data, poly)
                                if !poly  poly = 0xA001 end
                                # CRC-16 MODBUS HASHING ALGORITHM
                                var crc = 0xFFFF
                                for i:0..size(data)-1
                                  crc = crc ^ data[i]
                                  for j:0..7
                                    if crc & 1
                                      crc = (crc >> 1) ^ poly
                                    else
                                      crc = crc >> 1
                                    end
                                  end
                                end
                                return crc
                              end
                          
                              # encode using custom protocol 55 BB [payload length] [payload length] [payload] [crc] [crc]
                              def encode(payload)
                                var b = bytes()
                                b += self.header
                                b.add(size(payload), 2)   # add size as 2 bytes, little endian
                                b += bytes().fromstring(payload)
                                var msg_crc = self.crc16(b)
                                b.add(msg_crc, 2)       # crc 2 bytes, little endian
                                return b
                              end
                          
                              def encodenx(payload)
                                  var b = bytes().fromstring(payload)
                                  b += bytes('FFFFFF')
                                  return b
                              end
                          
                              def sendnx(payload)
                                  import string
                                  var payload_bin = self.encodenx(payload)
                                  self.ser.write(payload_bin)
                                  log(string.format("NXP: Nextion command sent = %s",str(payload_bin)), 3)       
                              end
                          
                              def send(payload)
                                  var payload_bin = self.encode(payload)
                                  if self.flash_mode==1
                                      log("NXP: skipped command becuase still flashing", 3)
                                  else 
                                      self.ser.write(payload_bin)
                                      log("NXP: payload sent = " + str(payload_bin), 3)
                                  end
                              end
                          
                              def write_to_nextion(b)
                                  self.ser.write(b)
                              end
                          
                              def screeninit()
                                  log("NXP: Screen Initialized")
                                  self.sendnx("recmod=1")        
                              end
                          
                              def write_block()
                                  
                                  import string
                                  log("FLH: Read block",3)
                                  while size(self.flash_buff)<self.flash_block_size && self.tcp.connected()
                                      if self.tcp.available()>0
                                          self.flash_buff += self.tcp.readbytes(4096)
                                      else
                                          tasmota.delay(50)
                                          log("FLH: Wait for available...",3)
                                      end
                                  end
                                  log("FLH: Buff size "+str(size(self.flash_buff)),3)
                                  var to_write
                                  if size(self.flash_buff)>self.flash_block_size
                                      to_write = self.flash_buff[0..self.flash_block_size-1]
                                      self.flash_buff = self.flash_buff[self.flash_block_size..]
                                  else
                                      to_write = self.flash_buff
                                      self.flash_buff = bytes()
                                  end
                                  log("FLH: Writing "+str(size(to_write)),3)
                                  var per = (self.flash_written*100)/self.flash_size
                                  if (self.last_per!=per) 
                                      self.last_per = per
                                      tasmota.publish_result(string.format("{\"Flashing\":{\"complete\": %d, \"time_elapsed\": %d}}",per , (tasmota.millis()-self.flash_start_millis)/1000), "RESULT") 
                                  end
                                  if size(to_write)>0
                                      self.flash_written += size(to_write)
                                      self.ser.write(to_write)
                                  end
                                  log("FLH: Total "+str(self.flash_written),3)
                                  if (self.flash_written==self.flash_size)
                                      log("FLH: Flashing complete - Time elapsed: %d", (tasmota.millis()-self.flash_start_millis)/1000)
                                      self.flash_mode = 0
                                      self.ser.deinit()
                                      self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                                  end
                          
                              end
                          
                              def every_100ms()
                                  import string
                                  if self.ser.available() > 0
                                      var msg = self.ser.read()
                                      if size(msg) > 0
                                          log(string.format("NXP: Received Raw = %s",str(msg)), 3)
                                          if (self.flash_mode==1)
                                              var strv = msg[0..-4].asstring()
                                              if string.find(strv,"comok 2")>=0
                                                  tasmota.delay(50)
                                                  log("FLH: Send (High Speed) flash start")
                                                  self.flash_start_millis = tasmota.millis()
                                                  #self.sendnx(string.format("whmi-wris %d,115200,res0",self.flash_size))
                                                  if self.flash_proto_version == 0
                                                      self.sendnx(string.format("whmi-wri %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                                  else
                                                      self.sendnx(string.format("whmi-wris %d,%d,res0",self.flash_size,self.flash_proto_baud))
                                                  end
                                                  if self.flash_proto_baud != 115200
                                                      tasmota.delay(50)
                                                      self.ser.deinit()
                                                      self.ser = serial(17, 16, self.flash_proto_baud, serial.SERIAL_8N1)
                                                  end
                                              elif size(msg)==1 && msg[0]==0x08
                                                  log("FLH: Waiting offset...",3)
                                                  self.awaiting_offset = 1
                                              elif size(msg)==4 && self.awaiting_offset==1
                                                  self.awaiting_offset = 0
                                                  self.flash_offset = msg.get(0,4)
                                                  log("FLH: Flash offset marker "+str(self.flash_offset),3)
                                                  if self.flash_offset != 0
                                                      self.open_url_at(self.url, self.flash_offset)
                                                      self.flash_written = self.flash_offset
                                                  end
                                                  self.write_block()
                                              elif size(msg)==1 && msg[0]==0x05
                                                  self.write_block()
                                              else
                                                  log("FLH: Something has gone wrong flashing display firmware ["+str(msg)+"]",2)
                                              end
                                          else
                                              var msg_list = self.split_55(msg)
                                              for i:0..size(msg_list)-1
                                                  msg = msg_list[i]
                                                  if size(msg) > 0
                                                      if msg == bytes('000000FFFFFF88FFFFFF')
                                                          self.screeninit()
                                                      elif size(msg)>=2 && msg[0]==0x55 && msg[1]==0xBB
                                                          var jm = string.format("{\"CustomRecv\":\"%s\"}",msg[4..-3].asstring())
                                                          tasmota.publish_result(jm, "RESULT")        
                                                      elif msg[0]==0x07 && size(msg)==1 # BELL/Buzzer
                                                          tasmota.cmd("buzzer 1,1")
                                                      else
                                                          var jm = string.format("{\"nextion\":\"%s\"}",str(msg[0..-4]))
                                                          tasmota.publish_result(jm, "RESULT")        
                                                      end
                                                  end       
                                              end
                                          end
                                      end
                                  end
                              end      
                          
                              def begin_nextion_flash()
                                  self.flash_written = 0
                                  self.awaiting_offset = 0
                                  self.flash_offset = 0
                                  self.sendnx('DRAKJHSUYDGBNCJHGJKSHBDN')
                                  self.sendnx('recmod=0')
                                  self.sendnx('recmod=0')
                                  self.flash_mode = 1
                                  self.sendnx("connect")        
                              end
                              
                              def open_url_at(url, pos)
                                  self.url = url
                                  import string
                                  var host
                                  var port
                                  var s1 = string.split(url,7)[1]
                                  var i = string.find(s1,":")
                                  var sa
                                  if i<0
                                      port = 80
                                      i = string.find(s1,"/")
                                      sa = string.split(s1,i)
                                      host = sa[0]
                                  else
                                      sa = string.split(s1,i)
                                      host = sa[0]
                                      s1 = string.split(sa[1],1)[1]
                                      i = string.find(s1,"/")
                                      sa = string.split(s1,i)
                                      port = int(sa[0])
                                  end
                                  var get = sa[1]
                                  log(string.format("FLH: host: %s, port: %s, get: %s",host,port,get))
                                  self.tcp = tcpclient()
                                  self.tcp.connect(host,port)
                                  log("FLH: Connected:"+str(self.tcp.connected()),3)
                                  var get_req = "GET "+get+" HTTP/1.0\r\n"
                                  get_req += string.format("Range: bytes=%d-\r\n", pos)
                                  get_req += string.format("HOST: %s:%s\r\n\r\n",host,port)
                                  self.tcp.write(get_req)
                                  var a = self.tcp.available()
                                  i = 1
                                  while a==0 && i<5
                                    tasmota.delay(100*i)
                                    tasmota.yield() 
                                    i += 1
                                    log("FLH: Retry "+str(i),3)
                                    a = self.tcp.available()
                                  end
                                  if a==0
                                      log("FLH: Nothing available to read!",3)
                                      return
                                  end
                                  var b = self.tcp.readbytes()
                                  i = 0
                                  var end_headers = false;
                                  var headers
                                  while i<size(b) && headers==nil
                                      if b[i..(i+3)]==bytes().fromstring("\r\n\r\n") 
                                          headers = b[0..(i+3)].asstring()
                                          self.flash_buff = b[(i+4)..]
                                      else
                                          i += 1
                                      end
                                  end
                                  #print(headers)
                                  # check http respose for code 200/206
                                  if string.find(headers,"200 OK")>0 || string.find(headers,"206 Partial Content")>0
                                      log("FLH: HTTP Respose is 200 OK or 206 Partial Content",3)
                                  else
                                      log("FLH: HTTP Respose is not 200 OK or 206 Partial Content",3)
                                      print(headers)
                                      return -1
                                  end
                                  # only set flash size if pos is zero
                                  if pos == 0
                                      # check http respose for content-length
                                      var tag = "Content-Length: "
                                      i = string.find(headers,tag)
                                      if (i>0) 
                                          var i2 = string.find(headers,"\r\n",i)
                                          var s = headers[i+size(tag)..i2-1]
                                          self.flash_size=int(s)
                                      end
                                      log("FLH: Flash file size: "+str(self.flash_size),3)
                                  end
                          
                              end
                          
                              def flash_nextion(url)
                                  self.flash_size = 0
                                  var res = self.open_url_at(url, 0)
                                  if res != -1
                                      self.begin_nextion_flash()
                                  end
                              end
                          
                              def init()
                                  log("NXP: Initializing Driver")
                                  self.ser = serial(17, 16, 115200, serial.SERIAL_8N1)
                                  self.flash_mode = 0
                                  self.flash_proto_version = 1
                                  self.flash_proto_baud = 921600
                              end
                          
                          end
                          
                          var nextion = Nextion()
                          
                          tasmota.add_driver(nextion)
                          
                          def get_current_version(cmd, idx, payload, payload_json)
                              import string
                              var version_of_this_script = 9
                              var jm = string.format("{\"nlui_driver_version\":\"%s\"}", version_of_this_script)
                              tasmota.publish_result(jm, "RESULT")
                          end
                          
                          tasmota.add_cmd('GetDriverVersion', get_current_version)
                          
                          def update_berry_driver(cmd, idx, payload, payload_json)
                              def task()
                                  import path
                                  import string
                          		if string.find(payload, ".tapp") > 0
                          		    print("tapp in URL; will do .tapp update and migration if necessary")
                          			
                          			if path.exists("autoexec.be")
                          			    print("autoexec.be found; will check for migration")
                          				var autoexecfile = open('autoexec.be')
                          				var line = autoexecfile.readline()
                          				autoexecfile.close()
                          				if string.find(line, "NSPanel Tasmota Lovelace UI Berry Driver") > 0
                          			        print("found lovelace berry driver, going to delete autoexec.be and .bec")
                          					path.remove("autoexec.be")
                          					path.remove("autoexec.bec")
                          				end
                          			end
                          			
                          			var r = tasmota.urlfetch(payload, "nsp-lovelace-driver.tapp")
                                      if r < 0
                                          print("Update failed")
                                      else
                                          tasmota.cmd("Restart 1")
                                      end
                          			
                          		elif string.find(payload, ".be") > 0
                          		    print("be in URL; will do .be update")
                          			if path.exists("nsp-lovelace-driver.tapp")
                          			    print("Error: there is the tapp version of the berry driver installed; cannot do .be update.")
                          			else
                                          var cl = webclient()
                                          cl.begin(payload)
                                          var r = cl.GET()
                                          if r == 200
                                              print("Sucessfully downloaded nspanel-lovelace-ui berry driver")
                                          else
                                              print("Error while downloading nspanel-lovelace-ui berry driver")
                                          end
                                          r = cl.write_file("autoexec.be")
                                          if r < 0
                                              print("Error while writeing nspanel-lovelace-ui berry driver")
                                          else
                                              print("Sucessfully written nspanel-lovelace-ui berry driver")
                                              tasmota.cmd("Restart 1")
                                          end
                          			end
                          		else
                          			print("invalid url filetype")
                          		end
                          		
                          		
                          		
                                  if path.exists("nsp-lovelace-driver.tapp")
                                      var r = string.find(payload, ".tapp")
                                      if r < 0
                                          print("URL doesn't contain .tapp skipping update")
                                      else
                          
                                      end
                                  else
                                      var r = string.find(payload, ".be")
                                      if r < 0
                                          print("URL doesn't contain .be skipping update")
                                      else
                                  
                                      end                
                                  end
                              end
                              tasmota.set_timer(0,task)
                              tasmota.resp_cmnd_done()
                          end
                          
                          tasmota.add_cmd('UpdateDriverVersion', update_berry_driver)
                          
                          def flash_nextion(cmd, idx, payload, payload_json)
                              def task()
                              nextion.flash_proto_version = 1
                              nextion.flash_proto_baud = 921600
                                  nextion.flash_nextion(payload)
                              end
                              tasmota.set_timer(0,task)
                              tasmota.resp_cmnd_done()
                          end
                          
                          def flash_nextion_adv(cmd, idx, payload, payload_json)
                              def task()        
                                  if idx==0
                                      nextion.flash_proto_version = 1
                                      nextion.flash_proto_baud = 921600
                                  elif idx==1
                                      nextion.flash_proto_version = 0
                                      nextion.flash_proto_baud = 921600
                                  elif idx==2
                                      nextion.flash_proto_version = 1
                                      nextion.flash_proto_baud = 115200
                                  elif idx==3
                                      nextion.flash_proto_version = 0
                                      nextion.flash_proto_baud = 115200
                                  elif idx==4
                                      nextion.flash_proto_version = 1
                                      nextion.flash_proto_baud = 256000
                                  elif idx==5
                                      nextion.flash_proto_version = 0
                                      nextion.flash_proto_baud = 256000
                                  elif idx==6
                                      nextion.ser.deinit()
                                      nextion.ser = serial(17, 16, 9600, serial.SERIAL_8N1)
                                      nextion.flash_proto_version = 0
                                      nextion.flash_proto_baud = 921600
                                  else
                                      nextion.flash_proto_version = 0
                                      nextion.flash_proto_baud = 115200
                                  end
                                  
                                  nextion.flash_nextion(payload)
                              end
                              tasmota.set_timer(0,task)
                              tasmota.resp_cmnd_done()
                          end
                          
                          def send_cmd(cmd, idx, payload, payload_json)
                              nextion.sendnx(payload)
                              tasmota.resp_cmnd_done()
                          end
                          
                          def send_cmd2(cmd, idx, payload, payload_json)
                              nextion.send(payload)
                              tasmota.resp_cmnd_done()
                          end
                          
                          tasmota.add_cmd('Nextion', send_cmd)
                          tasmota.add_cmd('CustomSend', send_cmd2)
                          tasmota.add_cmd('FlashNextion', flash_nextion)
                          tasmota.add_cmd('FlashNextionAdv', flash_nextion_adv)
                          
                          14.12.2024, 18:20:28.835	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online display firmware version => 53
                          14.12.2024, 18:20:28.852	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"nlui_driver_version":"9"}
                          14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current tasmota firmware version => 14.3.0
                          14.12.2024, 18:20:28.855	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online berry driver version => 9
                          14.12.2024, 18:20:28.882	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current berry driver version => 9
                          14.12.2024, 18:20:28.926	[info ]: javascript.0 (363) script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: hidden Cards disabled
                          
                          
                          T Offline
                          T Offline
                          TT-Tom
                          wrote on last edited by
                          #6649

                          @kerschte_de

                          aus dem Script diese Zeilen zeigen und ein Screenshot vom MQTT baum des Panel

                          // DE: Anpassen an die Verzeichnisse der MQTT-Adapter-Instanz
                          // EN: Adapt to the MQTT adapter instance directories
                          const NSPanelReceiveTopic: string = 'mqtt.0.SmartHome.NSPanel_1.tele.RESULT';
                          const NSPanelSendTopic: string = 'mqtt.0.SmartHome.NSPanel_1.cmnd.CustomSend';
                          

                          Gruß Tom
                          https://github.com/tt-tom17
                          Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

                          NSPanel Script Wiki
                          https://github.com/joBr99/nspanel-lovelace-ui/wiki

                          NSPanel Adapter Wiki
                          https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

                          K 1 Reply Last reply
                          0
                          • K Kerschte_de

                            @kerschte_de

                            da ist was durcheinandergekommen, da ich die maximale Zeichenzahl übersteige. Ich versuche es nochmal ab Zeile 572

                            javascript.0	18:20:28.125	info	Compiling TypeScript source script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT
                            javascript.0	18:20:28.391	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: source code did not change, using cached compilation result...
                            javascript.0	18:20:28.456	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: --- start of NsPanelTs: 0_userdata.0.NSPanel.1. ---
                            javascript.0	18:20:28.459	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: setObjects enabled - create Alias Channels possible
                            javascript.0	18:20:28.460	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: weather alias for accuweather.0. already exists
                            javascript.0	18:20:28.464	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: registered 41 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                            javascript.0	18:20:28.502	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Desired TFT Firmware: 53 / v4.4.0
                            javascript.0	18:20:28.502	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Installed TFT Firmware: 53 / v4.4.0
                            javascript.0	18:20:28.720	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Debug mode activated
                            javascript.0	18:20:28.788	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Tasmota Buzzer disabled
                            javascript.0	18:20:28.800	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: NaN W
                            javascript.0	18:20:28.801	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                            javascript.0	18:20:28.809	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting tasmota firmware version
                            javascript.0	18:20:28.810	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting current berry driver version
                            javascript.0	18:20:28.811	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: get_current_tasmota_ip_address: 192.168.188.240
                            javascript.0	18:20:28.811	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online berry driver version
                            javascript.0	18:20:28.811	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online TFT version
                            javascript.0	18:20:28.813	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: Requesting online firmware version
                            javascript.0	18:20:28.828	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: import adbase as ad from luibackend.config import LuiBackendConfig from luibackend.controller import LuiController from luibackend.mqtt import LuiMqttListener, LuiMqttSender from luibackend.updater import Updater import apis import json from typing import Literal class NsPanelLovelaceUIManager(ad.ADBase): def initialize(self): self.adapi = self.get_ad_api() self.adapi.log('Starting') apis.ad_api = self.adapi apis.ha_api = self.get_plugin_api("HASS") apis.mqtt_api = self.get_plugin_api("MQTT") cfg = self._cfg = LuiBackendConfig(apis.ha_api, self.args["config"]) use_api = cfg.get("use_api") == True topic_send = cfg.get("panelSendTopic") topic_recv = cfg.get("panelRecvTopic") api_panel_name = cfg.get("panelName") api_device_id = cfg.get("panelDeviceId") quiet = cfg.get("quiet") mqttsender = self._mqttsender = LuiMqttSender(apis.ha_api, use_api, topic_send, api_panel_name, quiet) self._controller = LuiController(cfg, mqttsender.send_mqtt_msg) desired_tasmota_driver_version = 8 desired_display_firmware_version = 53 version = "v4.3.3" model = cfg.get("model") if model == "us-l": desired_display_firmware_url = cfg._config.get("displayURL-US-L", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft") elif model == "us-p": desired_display_firmware_url = cfg._config.get("displayURL-US-P", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft") else: desired_display_firmware_url = cfg._config.get("displayURL-EU", f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft") desired_tasmota_driver_url = cfg._config.get("berryURL", "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be") mode = cfg.get("updateMode") updater = Updater(self.adapi.log, mqttsender, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url) # Request Tasmota Driver Version updater.request_berry_driver_version() LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, self._controller, updater) self.adapi.log(f'Started ({version})') # # helpers # def show_card(self, card_key: str) -> None: """Used to show card on panel""" msg = json.dumps({"CustomRecv":f"event,buttonPress2,navigate.{card_key},button"}) topic = self._cfg.get("panelRecvTopic") self._mqttsender.send_mqtt_msg(msg, topic) def navigate(self, direction: Literal['up', 'prev', 'next']) -> None: """Used to navigate different directions on the panel""" msg = json.dumps({"CustomRecv":f"event,buttonPress2,nav{direction.title()},button"}) topic = self._cfg.get("panelRecvTopic") self._mqttsender.send_mqtt_msg(msg, topic) @property def current_card(self) -> str: """Used to get the panel's current card""" return self._controller.current_card.key
                            javascript.0	18:20:28.832	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: # Sonoff NSPanel Tasmota Lovelace UI Berry Driver (Extended Flashing to faster speeds; improved Error Handling)| code by joBr99 # based on; # Sonoff NSPanel Tasmota (Nextion with Flashing) driver | code by peepshow-21 # based on; # Sonoff NSPanel Tasmota driver v0.47 | code by blakadder and s-hadinger # Example Flash # FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft # FlashNextion http://nspanel.pky.eu/lui.tft class Nextion : Driver static header = bytes('55BB') static flash_block_size = 4096 var flash_mode var flash_start_millis var flash_size var flash_written var flash_buff var flash_offset var flash_proto_version var flash_proto_baud var awaiting_offset var tcp var ser var last_per var url def split_55(b) var ret = [] var s = size(b) var i = s-2 # start from last-1 while i > 0 if b[i] == 0x55 && b[i+1] == 0xBB ret.push(b[i..s-1]) # push last msg to list b = b[(0..i-1)] # write the rest back to b end i -= 1 end ret.push(b) return ret end def crc16(data, poly) if !poly poly = 0xA001 end # CRC-16 MODBUS HASHING ALGORITHM var crc = 0xFFFF for i:0..size(data)-1 crc = crc ^ data[i] for j:0..7 if crc & 1 crc = (crc >> 1) ^ poly else crc = crc >> 1 end end end return crc end # encode using custom protocol 55 BB [payload length] [payload length] [payload] [crc] [crc] def encode(payload) var b = bytes() b += self.header b.add(size(payload), 2) # add size as 2 bytes, little endian b += bytes().fromstring(payload) var msg_crc = self.crc16(b) b.add(msg_crc, 2) # crc 2 bytes, little endian return b end def encodenx(payload) var b = bytes().fromstring(payload) b += bytes('FFFFFF') return b end def sendnx(payload) import string var payload_bin = self.encodenx(payload) self.ser.write(payload_bin) log(string.format("NXP: Nextion command sent = %s",str(payload_bin)), 3) end def send(payload) var payload_bin = self.encode(payload) if self.flash_mode==1 log("NXP: skipped command becuase still flashing", 3) else self.ser.write(payload_bin) log("NXP: payload sent = " + str(payload_bin), 3) end end def write_to_nextion(b) self.ser.write(b) end def screeninit() log("NXP: Screen Initialized") self.sendnx("recmod=1") end def write_block() import string log("FLH: Read block",3) while size(self.flash_buff)<self.flash_block_size && self.tcp.connected() if self.tcp.available()>0 self.flash_buff += self.tcp.readbytes(4096) else tasmota.delay(50) log("FLH: Wait for available...",3) end end log("FLH: Buff size "+str(size(self.flash_buff)),3) var to_write if size(self.flash_buff)>self.flash_block_size to_write = self.flash_buff[0..self.flash_block_size-1] self.flash_buff = self.flash_buff[self.flash_block_size..] else to_write = self.flash_buff self.flash_buff = bytes() end log("FLH: Writing "+str(size(to_write)),3) var per = (self.flash_written*100)/self.flash_size if (self.last_per!=per) self.last_per = per tasmota.publish_result(string.format("{\"Flashing\":{\"complete\": %d, \"time_elapsed\": %d}}",per , (tasmota.millis()-self.flash_start_millis)/1000), "RESULT") end if size(to_write)>0 self.flash_written += size(to_write) self.ser.write(to_write) end log("FLH: Total "+str(self.flash_written),3) if (self.flash_written==self.flash_size) log("FLH: Flashing complete - Time elapsed: %d", (tasmota.millis()-self.flash_start_millis)/1000) self.flash_mode = 0 self.ser.deinit() self.ser = serial(17, 16, 115200, serial.SERIAL_8N1) end end def every_100ms() import string if self.ser.available() > 0 var msg = self.ser.read() if size(msg) > 0 log(string.format("NXP: Received Raw = %s",str(msg)), 3) if (self.flash_mode==1) var strv = msg[0..-4].asstring() if string.find(strv,"comok 2")>=0 tasmota.delay(50) log("FLH: Send (High Speed) flash start") self.flash_start_millis = tasmota.millis() #self.sendnx(string.format("whmi-wris %d,115200,res0",self.flash_size)) if self.flash_proto_version == 0 self.sendnx(string.format("whmi-wri %d,%d,res0",self.flash_size,self.flash_proto_baud)) else self.sendnx(string.format("whmi-wris %d,%d,res0",self.flash_size,self.flash_proto_baud)) end if self.flash_proto_baud != 115200 tasmota.delay(50) self.ser.deinit() self.ser = serial(17, 16, self.flash_proto_baud, serial.SERIAL_8N1) end elif size(msg)==1 && msg[0]==0x08 log("FLH: Waiting offset...",3) self.awaiting_offset = 1 elif size(msg)==4 && self.awaiting_offset==1 self.awaiting_offset = 0 self.flash_offset = msg.get(0,4) log("FLH: Flash offset marker "+str(self.flash_offset),3) if self.flash_offset != 0 self.open_url_at(self.url, self.flash_offset) self.flash_written = self.flash_offset end self.write_block() elif size(msg)==1 && msg[0]==0x05 self.write_block() else log("FLH: Something has gone wrong flashing display firmware ["+str(msg)+"]",2) end else var msg_list = self.split_55(msg) for i:0..size(msg_list)-1 msg = msg_list[i] if size(msg) > 0 if msg == bytes('000000FFFFFF88FFFFFF') self.screeninit() elif size(msg)>=2 && msg[0]==0x55 && msg[1]==0xBB var jm = string.format("{\"CustomRecv\":\"%s\"}",msg[4..-3].asstring()) tasmota.publish_result(jm, "RESULT") elif msg[0]==0x07 && size(msg)==1 # BELL/Buzzer tasmota.cmd("buzzer 1,1") else var jm = string.format("{\"nextion\":\"%s\"}",str(msg[0..-4])) tasmota.publish_result(jm, "RESULT") end end end end end end end def begin_nextion_flash() self.flash_written = 0 self.awaiting_offset = 0 self.flash_offset = 0 self.sendnx('DRAKJHSUYDGBNCJHGJKSHBDN') self.sendnx('recmod=0') self.sendnx('recmod=0') self.flash_mode = 1 self.sendnx("connect") end def open_url_at(url, pos) self.url = url import string var host var port var s1 = string.split(url,7)[1] var i = string.find(s1,":") var sa if i<0 port = 80 i = string.find(s1,"/") sa = string.split(s1,i) host = sa[0] else sa = string.split(s1,i) host = sa[0] s1 = string.split(sa[1],1)[1] i = string.find(s1,"/") sa = string.split(s1,i) port = int(sa[0]) end var get = sa[1] log(string.format("FLH: host: %s, port: %s, get: %s",host,port,get)) self.tcp = tcpclient() self.tcp.connect(host,port) log("FLH: Connected:"+str(self.tcp.connected()),3) var get_req = "GET "+get+" HTTP/1.0\r\n" get_req += string.format("Range: bytes=%d-\r\n", pos) get_req += string.format("HOST: %s:%s\r\n\r\n",host,port) self.tcp.write(get_req) var a = self.tcp.available() i = 1 while a==0 && i<5 tasmota.delay(100*i) tasmota.yield() i += 1 log("FLH: Retry "+str(i),3) a = self.tcp.available() end if a==0 log("FLH: Nothing available to read!",3) return end var b = self.tcp.readbytes() i = 0 var end_headers = false; var headers while i<size(b) && headers==nil if b[i..(i+3)]==bytes().fromstring("\r\n\r\n") headers = b[0..(i+3)].asstring() self.flash_buff = b[(i+4)..] else i += 1 end end #print(headers) # check http respose for code 200/206 if string.find(headers,"200 OK")>0 || string.find(headers,"206 Partial Content")>0 log("FLH: HTTP Respose is 200 OK or 206 Partial Content",3) else log("FLH: HTTP Respose is not 200 OK or 206 Partial Content",3) print(headers) return -1 end # only set flash size if pos is zero if pos == 0 # check http respose for content-length var tag = "Content-Length: " i = string.find(headers,tag) if (i>0) var i2 = string.find(headers,"\r\n",i) var s = headers[i+size(tag)..i2-1] self.flash_size=int(s) end log("FLH: Flash file size: "+str(self.flash_size),3) end end def flash_nextion(url) self.flash_size = 0 var res = self.open_url_at(url, 0) if res != -1 self.begin_nextion_flash() end end def init() log("NXP: Initializing Driver") self.ser = serial(17, 16, 115200, serial.SERIAL_8N1) self.flash_mode = 0 self.flash_proto_version = 1 self.flash_proto_baud = 921600 end end var nextion = Nextion() tasmota.add_driver(nextion) def get_current_version(cmd, idx, payload, payload_json) import string var version_of_this_script = 9 var jm = string.format("{\"nlui_driver_version\":\"%s\"}", version_of_this_script) tasmota.publish_result(jm, "RESULT") end tasmota.add_cmd('GetDriverVersion', get_current_version) def update_berry_driver(cmd, idx, payload, payload_json) def task() import path import string if string.find(payload, ".tapp") > 0 print("tapp in URL; will do .tapp update and migration if necessary") if path.exists("autoexec.be") print("autoexec.be found; will check for migration") var autoexecfile = open('autoexec.be') var line = autoexecfile.readline() autoexecfile.close() if string.find(line, "NSPanel Tasmota Lovelace UI Berry Driver") > 0 print("found lovelace berry driver, going to delete autoexec.be and .bec") path.remove("autoexec.be") path.remove("autoexec.bec") end end var r = tasmota.urlfetch(payload, "nsp-lovelace-driver.tapp") if r < 0 print("Update failed") else tasmota.cmd("Restart 1") end elif string.find(payload, ".be") > 0 print("be in URL; will do .be update") if path.exists("nsp-lovelace-driver.tapp") print("Error: there is the tapp version of the berry driver installed; cannot do .be update.") else var cl = webclient() cl.begin(payload) var r = cl.GET() if r == 200 print("Sucessfully downloaded nspanel-lovelace-ui berry driver") else print("Error while downloading nspanel-lovelace-ui berry driver") end r = cl.write_file("autoexec.be") if r < 0 print("Error while writeing nspanel-lovelace-ui berry driver") else print("Sucessfully written nspanel-lovelace-ui berry driver") tasmota.cmd("Restart 1") end end else print("invalid url filetype") end if path.exists("nsp-lovelace-driver.tapp") var r = string.find(payload, ".tapp") if r < 0 print("URL doesn't contain .tapp skipping update") else end else var r = string.find(payload, ".be") if r < 0 print("URL doesn't contain .be skipping update") else end end end tasmota.set_timer(0,task) tasmota.resp_cmnd_done() end tasmota.add_cmd('UpdateDriverVersion', update_berry_driver) def flash_nextion(cmd, idx, payload, payload_json) def task() nextion.flash_proto_version = 1 nextion.flash_proto_baud = 921600 nextion.flash_nextion(payload) end tasmota.set_timer(0,task) tasmota.resp_cmnd_done() end def flash_nextion_adv(cmd, idx, payload, payload_json) def task() if idx==0 nextion.flash_proto_version = 1 nextion.flash_proto_baud = 921600 elif idx==1 nextion.flash_proto_version = 0 nextion.flash_proto_baud = 921600 elif idx==2 nextion.flash_proto_version = 1 nextion.flash_proto_baud = 115200 elif idx==3 nextion.flash_proto_version = 0 nextion.flash_proto_baud = 115200 elif idx==4 nextion.flash_proto_version = 1 nextion.flash_proto_baud = 256000 elif idx==5 nextion.flash_proto_version = 0 nextion.flash_proto_baud = 256000 elif idx==6 nextion.ser.deinit() nextion.ser = serial(17, 16, 9600, serial.SERIAL_8N1) nextion.flash_proto_version = 0 nextion.flash_proto_baud = 921600 else nextion.flash_proto_version = 0 nextion.flash_proto_baud = 115200 end nextion.flash_nextion(payload) end tasmota.set_timer(0,task) tasmota.resp_cmnd_done() end def send_cmd(cmd, idx, payload, payload_json) nextion.sendnx(payload) tasmota.resp_cmnd_done() end def send_cmd2(cmd, idx, payload, payload_json) nextion.send(payload) tasmota.resp_cmnd_done() end tasmota.add_cmd('Nextion', send_cmd) tasmota.add_cmd('CustomSend', send_cmd2) tasmota.add_cmd('FlashNextion', flash_nextion) tasmota.add_cmd('FlashNextionAdv', flash_nextion_adv)
                            javascript.0	18:20:28.835	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online display firmware version => 53
                            javascript.0	18:20:28.852	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"nlui_driver_version":"9"}
                            javascript.0	18:20:28.855	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current tasmota firmware version => 14.3.0
                            javascript.0	18:20:28.855	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: online berry driver version => 9
                            javascript.0	18:20:28.882	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: current berry driver version => 9
                            javascript.0	18:20:28.926	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: hidden Cards disabled
                            javascript.0	18:20:29.007	info	script.js.common.NSPanel.NSPanel_WZ_4_4_0_11_KeT: {"url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/149090497","assets_url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/149090497/assets","upload_url":"https://uploads.github.com/repos/joBr99/nspanel-lovelace-ui/releases/149090497/assets{?name,label}","html_url":"https://github.com/joBr99/nspanel-lovelace-ui/releases/tag/v4.4.0","id":149090497,"author":{"login":"joBr99","id":29555657,"node_id":"MDQ6VXNlcjI5NTU1NjU3","avatar_url":"https://avatars.githubusercontent.com/u/29555657?v=4","gravatar_id":"","url":"https://api.github.com/users/joBr99","html_url":"https://github.com/joBr99","followers_url":"https://api.github.com/users/joBr99/followers","following_url":"https://api.github.com/users/joBr99/following{/other_user}","gists_url":"https://api.github.com/users/joBr99/gists{/gist_id}","starred_url":"https://api.github.com/users/joBr99/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joBr99/subscriptions","organizations_url":"https://api.github.com/users/joBr99/orgs","repos_url":"https://api.github.com/users/joBr99/repos","events_url":"https://api.github.com/users/joBr99/events{/privacy}","received_events_url":"https://api.github.com/users/joBr99/received_events","type":"User","user_view_type":"public","site_admin":false},"node_id":"RE_kwDOGo1zRM4I4vDB","tag_name":"v4.4.0","target_commitish":"main","name":"v4.4.0 - Update for HA 2024.04","draft":false,"prerelease":false,"created_at":"2024-03-30T11:18:31Z","published_at":"2024-03-30T12:26:37Z","assets":[],"tarball_url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/tarball/v4.4.0","zipball_url":"https://api.github.com/repos/joBr99/nspanel-lovelace-ui/zipball/v4.4.0","body":"## Besides the Update of the App in HACS you need to do the following things:\r\n\r\n🔄 **Restart the AppDaemon Container**\r\n\r\n**Add the following workaround to your Home Assistant configuration.yaml**\r\n\r\nhttps://docs.nspanel.pky.eu/stable/prepare_ha/#workaround-for-homeassistant-202404\r\n\r\n🔄 **Restart Home Assistant**\r\n\r\n## New Features:\r\n\r\n- **Implemented changes to work with upcoming Homeassistant Version 2024.04 @joBr99**\r\n","mentions_count":1}
                            
                            T Offline
                            T Offline
                            TT-Tom
                            wrote on last edited by
                            #6650

                            @kerschte_de

                            kannst zurück setzen

                            Gruß Tom
                            https://github.com/tt-tom17
                            Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

                            NSPanel Script Wiki
                            https://github.com/joBr99/nspanel-lovelace-ui/wiki

                            NSPanel Adapter Wiki
                            https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

                            1 Reply Last reply
                            0
                            • T TT-Tom

                              @kerschte_de

                              aus dem Script diese Zeilen zeigen und ein Screenshot vom MQTT baum des Panel

                              // DE: Anpassen an die Verzeichnisse der MQTT-Adapter-Instanz
                              // EN: Adapt to the MQTT adapter instance directories
                              const NSPanelReceiveTopic: string = 'mqtt.0.SmartHome.NSPanel_1.tele.RESULT';
                              const NSPanelSendTopic: string = 'mqtt.0.SmartHome.NSPanel_1.cmnd.CustomSend';
                              
                              K Offline
                              K Offline
                              Kerschte_de
                              wrote on last edited by
                              #6651

                              @tt-tom
                              ... ja, mache ich:

                              /***** 1. Tasmota-Config *****/
                              
                                  // DE: Anpassen an die Verzeichnisse der MQTT-Adapter-Instanz
                                  // EN: Adapt to the MQTT adapter instance directories
                                  const NSPanelReceiveTopic: string = 'mqtt.0.RagowSmartHome.NSPanel_85C180.tele.RESULT';
                                  const NSPanelSendTopic: string = 'mqtt.0.RagowSmartHome.NSPanel_85C180.cmnd.CustomSend';
                              
                                  // DE: nur ändern, falls der User im Tasmota vor dem Kompilieren umbenannt wurde (Standard Tasmota: admin)
                                  // EN: only change if the user was renamed in Tasmota before compiling (default Tasmota: admin)
                                  const tasmota_web_admin_user: string = 'admin';
                                  
                                  // DE: setzten, falls "Web Admin Password" in Tasmota vergeben
                                  // EN set if "Web Admin Password" is assigned in Tasmota
                                  const tasmota_web_admin_password: string = '';
                              
                                  // DE: Setzen der bevorzugten Tasmota32-Version (für Updates)
                                  // EN: Set preferred Tasmota32 version (for updates)
                                  const tasmotaOtaVersion: string = 'tasmota32-DE.bin';
                                      // DE: Es können ebenfalls andere Versionen verwendet werden wie zum Beispiel:
                                      // EN: Other versions can also be used, such as:
                                      // 'tasmota32-nspanel.bin' or 'tasmota32.bin' or 'tasmota32-DE.bin' or etc.
                              

                              27c27a5a-c80a-4316-8db4-3e4f0dfc4f57-image.png

                              T 1 Reply Last reply
                              0
                              • K Kerschte_de

                                @tt-tom
                                ... ja, mache ich:

                                /***** 1. Tasmota-Config *****/
                                
                                    // DE: Anpassen an die Verzeichnisse der MQTT-Adapter-Instanz
                                    // EN: Adapt to the MQTT adapter instance directories
                                    const NSPanelReceiveTopic: string = 'mqtt.0.RagowSmartHome.NSPanel_85C180.tele.RESULT';
                                    const NSPanelSendTopic: string = 'mqtt.0.RagowSmartHome.NSPanel_85C180.cmnd.CustomSend';
                                
                                    // DE: nur ändern, falls der User im Tasmota vor dem Kompilieren umbenannt wurde (Standard Tasmota: admin)
                                    // EN: only change if the user was renamed in Tasmota before compiling (default Tasmota: admin)
                                    const tasmota_web_admin_user: string = 'admin';
                                    
                                    // DE: setzten, falls "Web Admin Password" in Tasmota vergeben
                                    // EN set if "Web Admin Password" is assigned in Tasmota
                                    const tasmota_web_admin_password: string = '';
                                
                                    // DE: Setzen der bevorzugten Tasmota32-Version (für Updates)
                                    // EN: Set preferred Tasmota32 version (for updates)
                                    const tasmotaOtaVersion: string = 'tasmota32-DE.bin';
                                        // DE: Es können ebenfalls andere Versionen verwendet werden wie zum Beispiel:
                                        // EN: Other versions can also be used, such as:
                                        // 'tasmota32-nspanel.bin' or 'tasmota32.bin' or 'tasmota32-DE.bin' or etc.
                                

                                27c27a5a-c80a-4316-8db4-3e4f0dfc4f57-image.png

                                T Offline
                                T Offline
                                TT-Tom
                                wrote on last edited by
                                #6652

                                @kerschte_de
                                der tele fehlt, der ist entscheidend

                                Gruß Tom
                                https://github.com/tt-tom17
                                Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

                                NSPanel Script Wiki
                                https://github.com/joBr99/nspanel-lovelace-ui/wiki

                                NSPanel Adapter Wiki
                                https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

                                K 1 Reply Last reply
                                0
                                • T TT-Tom

                                  @kerschte_de
                                  der tele fehlt, der ist entscheidend

                                  K Offline
                                  K Offline
                                  Kerschte_de
                                  wrote on last edited by
                                  #6653

                                  @tt-tom ... oh, sorry.

                                  b4a83219-57aa-46de-ac5d-afe1df3d83b0-image.png

                                  T 1 Reply Last reply
                                  0
                                  • K Kerschte_de

                                    @tt-tom ... oh, sorry.

                                    b4a83219-57aa-46de-ac5d-afe1df3d83b0-image.png

                                    T Offline
                                    T Offline
                                    TT-Tom
                                    wrote on last edited by
                                    #6654

                                    @kerschte_de

                                    okay hier stimmt alles, jetzt bitte die Config einer Seite wo keine Werte kommen und den passenden Objektbaum vom ioBroker

                                    Gruß Tom
                                    https://github.com/tt-tom17
                                    Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

                                    NSPanel Script Wiki
                                    https://github.com/joBr99/nspanel-lovelace-ui/wiki

                                    NSPanel Adapter Wiki
                                    https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

                                    K 2 Replies Last reply
                                    0
                                    • T TT-Tom

                                      @kerschte_de

                                      okay hier stimmt alles, jetzt bitte die Config einer Seite wo keine Werte kommen und den passenden Objektbaum vom ioBroker

                                      K Offline
                                      K Offline
                                      Kerschte_de
                                      wrote on last edited by
                                      #6655

                                      @tt-tom ja, gern.

                                      Die Hauptseite ("HOME") dient der Navigation auf Unterseiten. Aktuell habe ich nur noch die im Erdgeschoss aktiv. Dort sind testweise 2 Temperatur-Sensoren verlinkt ... es kommt jedoch nichts an Werten an. Die Seiten selbst funktionieren alle ... so auch wie der Screensaver und das komplette Service-Menu:

                                      //-- Anfang für eigene Seiten -- z.T. selbstdefinierte Aliase erforderlich ----------------
                                      //-- Start for your own pages -- some self-defined aliases required ----------------
                                      
                                          //-- https://github.com/joBr99/nspanel-lovelace-ui/wiki/NSPanel-Page-%E2%80%90-Typen_How-2_Beispiele
                                      
                                      //-- ##### ##### ##### KERSTEN #### ##### #####
                                      //Level 0
                                      
                                      let Navigation1: PageType =
                                      {
                                          'type': 'cardGrid',
                                          'heading': 'HOME',
                                          'useColor': true,
                                          'items': [
                                              /*PageItem*/{ navigate: true, id: 'SensorenEG', icon: 'home-floor-0',offColor: Menu, onColor: Menu, name: 'Sensoren EG'},
                                              //*PageItem*/{ navigate: true, id: 'SensorenOG', icon: 'home-floor-1',offColor: Menu, onColor: Menu, name: 'Sensoren OG'},
                                              //*PageItem*/{ navigate: true, id: 'SensorenKeller', icon: 'home-floor-negative-1',offColor: Menu, onColor: Menu, name: 'Sensoren Keller'},
                                              /*PageItem*/{ navigate: true, id: 'NSPanel_Service', icon: 'hammer-screwdriver',offColor: Menu, onColor: Menu, name: 'ServiceMenu'},
                                              //{ id: 'alias.0.NSPanel_1.TestFenster', offColor: MSRed, onColor: MSGreen, name: 'Büro Fenster'},
                                              //{ id: 'alias.0.NSPanel_1.Luftreiniger', icon: 'power', offColor: MSRed, onColor: MSGreen},
                                              //{ id: 'alias.0.NSPanel_1.TestBlind', icon: 'projector-screen', onColor: White, name: 'Beamer', secondRow: 'auch Text'},
                                              //{ id: 'alias.0.NSPanel_1.Kippfenster', useValue: true }
                                          ]
                                      };
                                      
                                      
                                           //Level 1
                                           let SensorenEG: PageType =
                                           {
                                               'type': 'cardGrid',
                                               'heading': 'Zigbee-Geräte EG',
                                               'useColor': true,
                                               'subPage': true,
                                               'parent': Navigation1,
                                               'items': [
                                                   { id: 'alias.0.NSPanel.1.1_Haus.EG.TempWZ.ACTUAL', name: 'WZ Temp.°C', offColor: MSRed, onColor: MSGreen, useValue: true, fontSize: 3, colorScale: {'val_min': 15, 'val_max': 35, 'val_best': 21} },
                                                   {},
                                                   { id: 'alias.0.NSPanel.1.1_Haus.EG.TempWZ.SECOND', name: 'WZ Luft %', offColor: MSYellow, onColor: MSYellow , useValue: true, fontSize: 3, colorScale: {'val_min': 30, 'val_max': 100, 'val_best': 60} },
                                                   { id: 'alias.0.NSPanel.1.1_Haus.EG.TempKueche.ACTUAL', name: 'Küche Temp.°C', offColor: MSRed, onColor: MSGreen, useValue: true, fontSize: 3, colorScale: {'val_min': 15, 'val_max': 35, 'val_best': 21} },
                                                   {},
                                                   { id: 'alias.0.NSPanel.1.1_Haus.EG.TempKueche.SECOND', name: 'Küche Luft %', offColor: MSYellow, onColor: MSYellow , useValue: true, fontSize: 3, colorScale: {'val_min': 30, 'val_max': 100, 'val_best': 60} },
                                               ]
                                           };
                                      
                                      
                                      //-- ENDE für eigene Seiten -- z.T. selbstdefinierte Aliase erforderlich -------------------------
                                      
                                      

                                      Hier noch die Einbindung der Seiten selbst:

                                      /***********************************************************************
                                       **                                                                   **
                                       **                           Configuration                           **
                                       **                                                                   **
                                       ***********************************************************************/
                                      
                                      export const config: Config = {
                                          // Seiteneinteilung / Page division
                                          // Hauptseiten / Mainpages
                                          pages: [
                                              Navigation1,
                                              //NSPanel_Service, //Auto-Alias Service Page
                                              //Unlock_Service            //Auto-Alias Service Page (Service Pages used with cardUnlock)
                                          ],
                                          // Unterseiten / Subpages
                                          subPages: [
                                              SensorenEG, // --> KeT hinzugefügt
                                              NSPanel_Service, //Auto-Alias Service Page --> KeT von der Hauptseite auf die Sub-Seite verschoben (über Auskommentierung)
                                              NSPanel_Service_SubPage, //Auto-Alias Service Page (only used with cardUnlock)
                                              NSPanel_Infos, //Auto-Alias Service Page
                                              NSPanel_Wifi_Info_1, //Auto-Alias Service Page
                                              NSPanel_Wifi_Info_2, //Auto-Alias Service Page
                                              NSPanel_Sensoren, //Auto-Alias Service Page
                                              NSPanel_Hardware, //Auto-Alias Service Page
                                              NSPanel_IoBroker, //Auot-Alias Service Page
                                              NSPanel_Einstellungen, //Auto-Alias Service Page
                                              NSPanel_Screensaver, //Auto-Alias Service Page
                                              NSPanel_ScreensaverDimmode, //Auto-Alias Service Page
                                              NSPanel_ScreensaverBrightness, //Auto-Alias Service Page
                                              NSPanel_ScreensaverLayout, //Auto-Alias Service Page
                                              NSPanel_ScreensaverWeather, //Auto-Alias Service Page
                                              NSPanel_ScreensaverDateformat, //Auto-Alias Service Page
                                              NSPanel_ScreensaverIndicators, //Auto-Alias Service Page
                                              NSPanel_Relays, //Auto-Alias Service Page
                                              NSPanel_Script, //Auto-Alias Service Page
                                              NSPanel_Firmware, //Auto-Alias Service Page
                                              NSPanel_FirmwareTasmota, //Auto-Alias Service Page
                                              NSPanel_FirmwareBerry, //Auto-Alias Service Page
                                              NSPanel_FirmwareNextion, //Auto-Alias Service Page
                                          ],
                                      
                                      

                                      und hier der Sreenshot der beiden Temperatur-Sensoren:
                                      e1a77316-92dd-492a-9da3-f256db1f7263-image.png

                                      T 1 Reply Last reply
                                      0
                                      • T TT-Tom

                                        @kerschte_de

                                        okay hier stimmt alles, jetzt bitte die Config einer Seite wo keine Werte kommen und den passenden Objektbaum vom ioBroker

                                        K Offline
                                        K Offline
                                        Kerschte_de
                                        wrote on last edited by
                                        #6656

                                        @tt-tom
                                        Das Konstrukt hatte in der alten Umgebung funktioniert. Testweise hatte ich es auf etliche Sensoren in den unterschiedlichen Etagen mal aufgebaut. Aktuell funktionieren die Seiten weiterhin, nur die Inhalte der Sensoren werden nicht transferiert.

                                        1 Reply Last reply
                                        0
                                        • K Kerschte_de

                                          @tt-tom ja, gern.

                                          Die Hauptseite ("HOME") dient der Navigation auf Unterseiten. Aktuell habe ich nur noch die im Erdgeschoss aktiv. Dort sind testweise 2 Temperatur-Sensoren verlinkt ... es kommt jedoch nichts an Werten an. Die Seiten selbst funktionieren alle ... so auch wie der Screensaver und das komplette Service-Menu:

                                          //-- Anfang für eigene Seiten -- z.T. selbstdefinierte Aliase erforderlich ----------------
                                          //-- Start for your own pages -- some self-defined aliases required ----------------
                                          
                                              //-- https://github.com/joBr99/nspanel-lovelace-ui/wiki/NSPanel-Page-%E2%80%90-Typen_How-2_Beispiele
                                          
                                          //-- ##### ##### ##### KERSTEN #### ##### #####
                                          //Level 0
                                          
                                          let Navigation1: PageType =
                                          {
                                              'type': 'cardGrid',
                                              'heading': 'HOME',
                                              'useColor': true,
                                              'items': [
                                                  /*PageItem*/{ navigate: true, id: 'SensorenEG', icon: 'home-floor-0',offColor: Menu, onColor: Menu, name: 'Sensoren EG'},
                                                  //*PageItem*/{ navigate: true, id: 'SensorenOG', icon: 'home-floor-1',offColor: Menu, onColor: Menu, name: 'Sensoren OG'},
                                                  //*PageItem*/{ navigate: true, id: 'SensorenKeller', icon: 'home-floor-negative-1',offColor: Menu, onColor: Menu, name: 'Sensoren Keller'},
                                                  /*PageItem*/{ navigate: true, id: 'NSPanel_Service', icon: 'hammer-screwdriver',offColor: Menu, onColor: Menu, name: 'ServiceMenu'},
                                                  //{ id: 'alias.0.NSPanel_1.TestFenster', offColor: MSRed, onColor: MSGreen, name: 'Büro Fenster'},
                                                  //{ id: 'alias.0.NSPanel_1.Luftreiniger', icon: 'power', offColor: MSRed, onColor: MSGreen},
                                                  //{ id: 'alias.0.NSPanel_1.TestBlind', icon: 'projector-screen', onColor: White, name: 'Beamer', secondRow: 'auch Text'},
                                                  //{ id: 'alias.0.NSPanel_1.Kippfenster', useValue: true }
                                              ]
                                          };
                                          
                                          
                                               //Level 1
                                               let SensorenEG: PageType =
                                               {
                                                   'type': 'cardGrid',
                                                   'heading': 'Zigbee-Geräte EG',
                                                   'useColor': true,
                                                   'subPage': true,
                                                   'parent': Navigation1,
                                                   'items': [
                                                       { id: 'alias.0.NSPanel.1.1_Haus.EG.TempWZ.ACTUAL', name: 'WZ Temp.°C', offColor: MSRed, onColor: MSGreen, useValue: true, fontSize: 3, colorScale: {'val_min': 15, 'val_max': 35, 'val_best': 21} },
                                                       {},
                                                       { id: 'alias.0.NSPanel.1.1_Haus.EG.TempWZ.SECOND', name: 'WZ Luft %', offColor: MSYellow, onColor: MSYellow , useValue: true, fontSize: 3, colorScale: {'val_min': 30, 'val_max': 100, 'val_best': 60} },
                                                       { id: 'alias.0.NSPanel.1.1_Haus.EG.TempKueche.ACTUAL', name: 'Küche Temp.°C', offColor: MSRed, onColor: MSGreen, useValue: true, fontSize: 3, colorScale: {'val_min': 15, 'val_max': 35, 'val_best': 21} },
                                                       {},
                                                       { id: 'alias.0.NSPanel.1.1_Haus.EG.TempKueche.SECOND', name: 'Küche Luft %', offColor: MSYellow, onColor: MSYellow , useValue: true, fontSize: 3, colorScale: {'val_min': 30, 'val_max': 100, 'val_best': 60} },
                                                   ]
                                               };
                                          
                                          
                                          //-- ENDE für eigene Seiten -- z.T. selbstdefinierte Aliase erforderlich -------------------------
                                          
                                          

                                          Hier noch die Einbindung der Seiten selbst:

                                          /***********************************************************************
                                           **                                                                   **
                                           **                           Configuration                           **
                                           **                                                                   **
                                           ***********************************************************************/
                                          
                                          export const config: Config = {
                                              // Seiteneinteilung / Page division
                                              // Hauptseiten / Mainpages
                                              pages: [
                                                  Navigation1,
                                                  //NSPanel_Service, //Auto-Alias Service Page
                                                  //Unlock_Service            //Auto-Alias Service Page (Service Pages used with cardUnlock)
                                              ],
                                              // Unterseiten / Subpages
                                              subPages: [
                                                  SensorenEG, // --> KeT hinzugefügt
                                                  NSPanel_Service, //Auto-Alias Service Page --> KeT von der Hauptseite auf die Sub-Seite verschoben (über Auskommentierung)
                                                  NSPanel_Service_SubPage, //Auto-Alias Service Page (only used with cardUnlock)
                                                  NSPanel_Infos, //Auto-Alias Service Page
                                                  NSPanel_Wifi_Info_1, //Auto-Alias Service Page
                                                  NSPanel_Wifi_Info_2, //Auto-Alias Service Page
                                                  NSPanel_Sensoren, //Auto-Alias Service Page
                                                  NSPanel_Hardware, //Auto-Alias Service Page
                                                  NSPanel_IoBroker, //Auot-Alias Service Page
                                                  NSPanel_Einstellungen, //Auto-Alias Service Page
                                                  NSPanel_Screensaver, //Auto-Alias Service Page
                                                  NSPanel_ScreensaverDimmode, //Auto-Alias Service Page
                                                  NSPanel_ScreensaverBrightness, //Auto-Alias Service Page
                                                  NSPanel_ScreensaverLayout, //Auto-Alias Service Page
                                                  NSPanel_ScreensaverWeather, //Auto-Alias Service Page
                                                  NSPanel_ScreensaverDateformat, //Auto-Alias Service Page
                                                  NSPanel_ScreensaverIndicators, //Auto-Alias Service Page
                                                  NSPanel_Relays, //Auto-Alias Service Page
                                                  NSPanel_Script, //Auto-Alias Service Page
                                                  NSPanel_Firmware, //Auto-Alias Service Page
                                                  NSPanel_FirmwareTasmota, //Auto-Alias Service Page
                                                  NSPanel_FirmwareBerry, //Auto-Alias Service Page
                                                  NSPanel_FirmwareNextion, //Auto-Alias Service Page
                                              ],
                                          
                                          

                                          und hier der Sreenshot der beiden Temperatur-Sensoren:
                                          e1a77316-92dd-492a-9da3-f256db1f7263-image.png

                                          T Offline
                                          T Offline
                                          TT-Tom
                                          wrote on last edited by
                                          #6657

                                          @kerschte_de

                                          du hast zwei Fehler in deinem Setup.

                                          let SensorenEG: PageType =
                                               {
                                                   'type': 'cardGrid',
                                                   'heading': 'Zigbee-Geräte EG',
                                                   'useColor': true,
                                                   'subPage': true,
                                                   'parent': Navigation1,
                                                   'items': [
                                                       { id: 'alias.0.NSPanel.1.1_Haus.EG.TempWZ.ACTUAL', name: 'WZ Temp.°C', offColor: MSRed, onColor: MSGreen, useValue: true, fontSize: 3, colorScale: {'val_min': 15, 'val_max': 35, 'val_best': 21} },
                                                       {},
                                                       { id: 'alias.0.NSPanel.1.1_Haus.EG.TempWZ.SECOND', name: 'WZ Luft %', offColor: MSYellow, onColor: MSYellow , useValue: true, fontSize: 3, colorScale: {'val_min': 30, 'val_max': 100, 'val_best': 60} },
                                                       { id: 'alias.0.NSPanel.1.1_Haus.EG.TempKueche.ACTUAL', name: 'Küche Temp.°C', offColor: MSRed, onColor: MSGreen, useValue: true, fontSize: 3, colorScale: {'val_min': 15, 'val_max': 35, 'val_best': 21} },
                                                       {},
                                                       { id: 'alias.0.NSPanel.1.1_Haus.EG.TempKueche.SECOND', name: 'Küche Luft %', offColor: MSYellow, onColor: MSYellow , useValue: true, fontSize: 3, colorScale: {'val_min': 30, 'val_max': 100, 'val_best': 60} },
                                                   ]
                                               };
                                          

                                          in einer Page Config, werden keine Datenpunkte angegeben, sonder immer nur die Cannel.

                                          { id: 'alias.0.NSPanel.1.1_Haus.EG.TempWZ', name: 'WZ Temp.°C', offColor: MSRed, onColor: MSGreen, useValue: true, fontSize: 3, colorScale: {'val_min': 15, 'val_max': 35, 'val_best': 21} },
                                          

                                          dein Channel hat für diese Kombi (ACTUAL, SECOND) den falschen Typ. Diese Datenpunkte werden nur beim Thermostat ausgewertet, was auch eine andere Page zur Folge hat. Beim Type Temperature wird nur der ACTUAL ausgewertet vom Script.
                                          Bedeutet du musst für jeden Sensor einen eigenen Alias erstellen.

                                          Im Screensaver sieht die Sache anders aus dort wird direkt auf den Datenpunkt verwiesen. Beispiel hier

                                          // leftScreensaverEntity 1 (only Advanced Screensaver)
                                                      {
                                                          ScreensaverEntity: NSPanel_Path + 'Sensor.ANALOG.Temperature',
                                                          ScreensaverEntityFactor: 1,
                                                          ScreensaverEntityDecimalPlaces: 1,
                                                          ScreensaverEntityIconOn: 'thermometer',
                                                          ScreensaverEntityIconOff: null,
                                                          ScreensaverEntityText: 'Temperatur',
                                                          ScreensaverEntityUnitText: '°C',
                                                          ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 35, 'val_best': 22}
                                                      },
                                          

                                          Gruß Tom
                                          https://github.com/tt-tom17
                                          Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

                                          NSPanel Script Wiki
                                          https://github.com/joBr99/nspanel-lovelace-ui/wiki

                                          NSPanel Adapter Wiki
                                          https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

                                          K 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          643

                                          Online

                                          32.4k

                                          Users

                                          81.3k

                                          Topics

                                          1.3m

                                          Posts
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Recent
                                          • Tags
                                          • Unread 0
                                          • Categories
                                          • Unreplied
                                          • Popular
                                          • GitHub
                                          • Docu
                                          • Hilfe