Weiter zum Inhalt
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Hell
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dunkel
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

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

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. Zendure SmartMode:1 SolarFlow2400 AC SolarFlow800 ( u. Pro)

NEWS

  • Monatsrückblick Januar/Februar 2026 ist online!
    BluefoxB
    Bluefox
    18
    1
    686

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    18
    1
    5.8k

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

Zendure SmartMode:1 SolarFlow2400 AC SolarFlow800 ( u. Pro)

Geplant Angeheftet Gesperrt Verschoben JavaScript
232 Beiträge 10 Kommentatoren 16.1k Aufrufe 10 Beobachtet
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • B Berny-K

    Hallo,
    Ich haben mir einen Solarflow 800 pro zugelegt und auf der Suche nach einer Möglichkeit diesen über iobroker auszuwerten und zu steuern hier gelandet.
    Hoffe ich bin mit meinen Fragen hier überhaupt richtig?
    Ich bin dabei mein vorhandenes BKW etwas auszubauen und würde gerne meinen IR-Lesekopf mit Tasmota weiter nutzen und auf Basis dieser verfügbaren Daten im iobroker den Solarflow 800 Pro ansteuern um eine Null-Einspeisung zu realisieren.
    Das Script habe ich schon Mal im iobroker am laufen und sehe auch entsprechende Daten.
    Ich habe aber bisher noch keine Hinweise gefunden wie ich meinen Plan realisieren könnte.
    Könnte mir dazu vielleicht jemand auf die Sprünge helfen oder geht das auf diese Weise gar nicht?

    S Offline
    S Offline
    Schimi
    schrieb am zuletzt editiert von
    #215

    @Berny-K schaue dir mal das Script an, vielleicjt erledigt das schon alles was du möchtest 😉

    https://forum.iobroker.net/topic/82723/typeskript-zendure-solarflow-2400-ac-evcc-steuerung

    B 1 Antwort Letzte Antwort
    0
    • S Schimi

      @Berny-K schaue dir mal das Script an, vielleicjt erledigt das schon alles was du möchtest 😉

      https://forum.iobroker.net/topic/82723/typeskript-zendure-solarflow-2400-ac-evcc-steuerung

      B Offline
      B Offline
      Berny-K
      schrieb am zuletzt editiert von
      #216

      @Schimi Vielen Dank für den Tipp, das schaue ich mir an. Den Script hier werde ich trotzdem auch brauchen um die Daten auszulesen, oder?

      1 Antwort Letzte Antwort
      0
      • S Offline
        S Offline
        Schimi
        schrieb am zuletzt editiert von
        #217

        ich nutze das Skript hier, damit der SmartMode gesetzt wird... habe es nie kontrolliert ob es wirklich nötig ist.....

        Aber das funktioniert alles sehr gut parallel

        B 1 Antwort Letzte Antwort
        0
        • S Schimi

          ich nutze das Skript hier, damit der SmartMode gesetzt wird... habe es nie kontrolliert ob es wirklich nötig ist.....

          Aber das funktioniert alles sehr gut parallel

          B Offline
          B Offline
          Berny-K
          schrieb am zuletzt editiert von
          #218

          @Schimi Danke, gut zu wissen, mal sehen ob ich das hin bekomme

          1 Antwort Letzte Antwort
          0
          • D Offline
            D Offline
            Daniel 8
            schrieb am zuletzt editiert von
            #219

            Es ist sehr ruhig hier geworden. Nochmals vielen Dank Für das Script. Im Moment bin ich noch am Script umbauen, da ja das neue Firmware Update meint, wenn es den minSoc unterschreitet vom Netz laden zu müssen

            Solarflow 800 Pro mit 1,3 Kwp / Iobroker / Homematic / Shellys / Mediola / Intertechno

            maxclaudiM 1 Antwort Letzte Antwort
            0
            • D Daniel 8

              Es ist sehr ruhig hier geworden. Nochmals vielen Dank Für das Script. Im Moment bin ich noch am Script umbauen, da ja das neue Firmware Update meint, wenn es den minSoc unterschreitet vom Netz laden zu müssen

              maxclaudiM Offline
              maxclaudiM Offline
              maxclaudi
              schrieb am zuletzt editiert von maxclaudi
              #220

              @Daniel-8 sagte in Zendure SmartMode:1 SolarFlow2400 AC SolarFlow800 ( u. Pro):

              ...Im Moment bin ich noch am Script umbauen, da ja das neue Firmware Update meint, wenn es den minSoc unterschreitet vom Netz laden zu müssen

              Hallo Daniel, freut mich von Dir mal wieder zu lesen, wie geht's Dir?

              Ja Zendure macht gerade viel ....
              Es wird immer mehr reglementiert. Vieles meiner Meinung nach unnötig und wahrscheinlich zum (Eigen-)Schutz.
              Persönlich würde ich abwarten und neue Firmware nicht sofort aktualisieren.
              Setze doch MinSoc sehr tief und baue einen Entladeschutz ein.
              Der verhindert dann rechtzeitig, dass Batterien weiter entladen werden noch bevor minSoc erreicht wird.

              Beispiel Ausschnitt einer Steuerung von mir:
              8f148a02-f02b-4f23-a03b-81edf9e089f1-image.png

              Ich schreibe meistens sehr direkt – bitte nicht falsch verstehen, es ist nie böse gemeint. Das ist einfach mein Stil und niemals abwertend gemeint.

              1 Antwort Letzte Antwort
              0
              • D Offline
                D Offline
                Daniel 8
                schrieb am zuletzt editiert von
                #221

                Mir geht es soweit sehr gut. Und bei dir auch alles in Ordnung?

                Ja das ist auch eine Idee mit dem Entladeachutz. Das könnte ich ja auch mit soc triggern. Du machst das ganze ja mit volt. Bin nur noch nicht ganz schlau geworden was du mit deinen internen Variablen da alles abfragst. Ich denke du triggerst auf Volt oder?
                Dann müsste ich nur mein ganzes Script umbauen, da ich überall mir soc getrickert habe wann er aufhören soll zu entladen und starten soll. Sollte aber nicht das große Problem sein.

                Solarflow 800 Pro mit 1,3 Kwp / Iobroker / Homematic / Shellys / Mediola / Intertechno

                1 Antwort Letzte Antwort
                0
                • D Offline
                  D Offline
                  Daniel 8
                  schrieb am zuletzt editiert von Daniel 8
                  #222

                  So script ist umgebaut. War ja eigentlich ganz einfach. Ich habe einfach alle minsoc wo ich bis jetzt von mqtt bezogen habe durch eine in Objekte erstellten Variable ersetzt. Somit kann ich mit der den unteren soc steuern. Muss nur mal sehen wie sich der Speicher dann verhält ob er auch in standby dann geht wenn er den unteren soc nicht in Wirklichkeit erreicht oder ob dann der standbyverbrauch sich erhöht.

                  Er zeigt zumindest mal standby an wenn ich Ausgabe 0 mache.

                  Solarflow 800 Pro mit 1,3 Kwp / Iobroker / Homematic / Shellys / Mediola / Intertechno

                  1 Antwort Letzte Antwort
                  0
                  • D Offline
                    D Offline
                    Daniel 8
                    schrieb am zuletzt editiert von
                    #223

                    Ergebnis war positiv heute Nacht. Er hat wie sonst auch ca. 2% verloren.

                    Die Änderung am Script war doch nicht so einfach, weil er am unteren soc nicht abgeschaltet hat. Habe es bisschen geändert und hoffe das es so läuft.

                    Solarflow 800 Pro mit 1,3 Kwp / Iobroker / Homematic / Shellys / Mediola / Intertechno

                    maxclaudiM 2 Antworten Letzte Antwort
                    0
                    • D Daniel 8

                      Ergebnis war positiv heute Nacht. Er hat wie sonst auch ca. 2% verloren.

                      Die Änderung am Script war doch nicht so einfach, weil er am unteren soc nicht abgeschaltet hat. Habe es bisschen geändert und hoffe das es so läuft.

                      maxclaudiM Offline
                      maxclaudiM Offline
                      maxclaudi
                      schrieb am zuletzt editiert von maxclaudi
                      #224

                      @Daniel-8 sagte in Zendure SmartMode:1 SolarFlow2400 AC SolarFlow800 ( u. Pro):

                      Die Änderung am Script war doch nicht so einfach, weil er am unteren soc nicht abgeschaltet hat. Habe es bisschen geändert und hoffe das es so läuft.

                      Am unteren SOC nicht abgeschaltet?
                      Wie meinst Du das?

                      Du hast minSoc z. B. auf 10 %, dann eine Entladesperre bei z. B. 15 % eingebaut und die wurde nicht beachtet und es wurde weiter entladen?

                      Mein Tipp:
                      Eine Entladesperre nur nach minVolt der Batterien setzen.
                      Spannung ist ein direkter Messwert, SOC bleibt immer ein berechneter Zustand und setzt regelmäßiges Kalibrieren voraus.

                      Edit / PS: Wenn längere Zeit nicht vollständig geladen oder entladen wird, driftet der SOC zwangsläufig.
                      Ohne Kalibrierung kann SOC mehrere Prozent danebenliegen.

                      Sieht man schön, wenn man sich minVol, maxVol und SOC-Werte visuell anzeigen lässt und diese immer wieder mal vergleicht.

                      Ich schreibe meistens sehr direkt – bitte nicht falsch verstehen, es ist nie böse gemeint. Das ist einfach mein Stil und niemals abwertend gemeint.

                      1 Antwort Letzte Antwort
                      0
                      • D Offline
                        D Offline
                        Daniel 8
                        schrieb am zuletzt editiert von Daniel 8
                        #225

                        Ich bringe den Speicher jetzt im Sommer regelmäßig voll. Somit ist er auch kalibriert.
                        Ja das war noch ein ScriptProblem, da ich mehrere gleiche abfragen in dem Block habe. Ist bisschen schwierig mit dem ganzen bypass Zeug noch. Aber jetzt schaltet er ab sobald er 0,5 unter meiner soc entladesperre ist. Damit kann ich leben.
                        Die liegt bei 10% aktuell. Den soc im zendure habe ich auf die minimalen 5% gestellt. Wenn er die 2 Prozent über Nacht verliert, dann sollte es aufgehen.

                        Solarflow 800 Pro mit 1,3 Kwp / Iobroker / Homematic / Shellys / Mediola / Intertechno

                        1 Antwort Letzte Antwort
                        1
                        • D Offline
                          D Offline
                          Daniel 8
                          schrieb am zuletzt editiert von
                          #226

                          Es.war bzw. Ist nicht ganz so einfach wie gedacht. Jetzt geht der 800Pro nicht mehr in den Bypass und somit lädt er immer bisschen in den Akku und entlädt dann wieder bis zum man soc der variable. Durch das was der pro eben denkt er darf weiter entladen weil der soc ja viel niedriger eingestellt ist. Somit schaltet er nicht in bypass

                          Solarflow 800 Pro mit 1,3 Kwp / Iobroker / Homematic / Shellys / Mediola / Intertechno

                          1 Antwort Letzte Antwort
                          0
                          • C Offline
                            C Offline
                            cbrocker
                            schrieb am zuletzt editiert von
                            #227

                            Hallo,
                            ich lese hier hin und wieder mit und habe mir auch den Adapter von nograx mal heruntergeladen, aber noch nicht wirklich eingerichtet. Bisher lese ich ein paar Daten vom SF800 per http request aus.

                            Ich habe mal mit KI ein Script erstellen lassen, das mir den Tagesertrag anhand der laufenden PV-Produktion berechnet, aber der Wert stimmt nicht ganz mit dem in der App überein.

                            Frage: werden im Adapter von nograx die PV-Daten (Erträge für Tag, Monat, Jahr usw.) ausgelesen oder berechnet?

                            Danke

                            Proxmox Cluster mit ioBroker, Wireguard, HomeAssistant (Testsystem), paperlessNGX, MariaDB, PiHole, Grafana, InfluxDB, 1 x BKW 600 Wp, 2 x BKW 400 Wp, 2 x SolarFlow 800 Pro mit 11,52 kWh Akku und 3,48 kWp, OpenDTU, AhoyDTU, HmIP, Shellys, AVM LAN/WLAN

                            maxclaudiM 2 Antworten Letzte Antwort
                            0
                            • C cbrocker

                              Hallo,
                              ich lese hier hin und wieder mit und habe mir auch den Adapter von nograx mal heruntergeladen, aber noch nicht wirklich eingerichtet. Bisher lese ich ein paar Daten vom SF800 per http request aus.

                              Ich habe mal mit KI ein Script erstellen lassen, das mir den Tagesertrag anhand der laufenden PV-Produktion berechnet, aber der Wert stimmt nicht ganz mit dem in der App überein.

                              Frage: werden im Adapter von nograx die PV-Daten (Erträge für Tag, Monat, Jahr usw.) ausgelesen oder berechnet?

                              Danke

                              maxclaudiM Offline
                              maxclaudiM Offline
                              maxclaudi
                              schrieb am zuletzt editiert von maxclaudi
                              #228

                              @cbrocker sagte in Zendure SmartMode:1 SolarFlow2400 AC SolarFlow800 ( u. Pro):

                              Hallo,
                              ich lese hier hin und wieder mit und habe mir auch den Adapter von nograx mal heruntergeladen, aber noch nicht wirklich eingerichtet. Bisher lese ich ein paar Daten vom SF800 per http request aus.

                              Ich habe mal mit KI ein Script erstellen lassen, das mir den Tagesertrag anhand der laufenden PV-Produktion berechnet, aber der Wert stimmt nicht ganz mit dem in der App überein.

                              Frage: werden im Adapter von nograx die PV-Daten (Erträge für Tag, Monat, Jahr usw.) ausgelesen oder berechnet?

                              Danke

                              @cbrocker, zu Detailfragen zum Adapter wendest du dich am besten direkt an den Entwickler im entsprechenden Thread.

                              Ich nutze den Adapter selbst nicht mehr, seit die Funktion setDeviceAutomationInOutLimit eingeführt wurde, und bin daher bei den aktuellen Versionen nicht mehr im Thema.
                              In meinem zenSDK-Ansatz hier geht es primär um die direkte Steuerung ohne solche kombinierten Datenpunkte.

                              Zu deiner Frage bzgl. der Ertragsdaten:
                              Zendure liefert über MQTT oft nur die Momentanwerte (Watt).
                              Die App-Statistiken (Tag/Monat) werden meist in der Cloud berechnet.
                              Wenn der Adapter diese Werte anzeigt, kommen sie entweder per Cloud-API-Abfrage (langsam) oder der Adapter berechnet sie lokal per Integral-Funktion (was bei Übertragungslücken ungenau ist). Das erklärt auch, warum KI-Skripte evtl. oft anders sind bzw. andere Werte liefern.

                              Ich schreibe meistens sehr direkt – bitte nicht falsch verstehen, es ist nie böse gemeint. Das ist einfach mein Stil und niemals abwertend gemeint.

                              1 Antwort Letzte Antwort
                              0
                              • C Offline
                                C Offline
                                cbrocker
                                schrieb am zuletzt editiert von
                                #229

                                @maxclaudi
                                danke für die Infos.
                                ich lese die Daten bisher auch per http request aus (zenSDK).
                                Was macht die Funktion setDeviceAutomationInOutLimit genau? Die Funktion ist aber nur im Adapter? Also nicht von Zendure selber?

                                Ich möchte auch ohne Adapter und ohne MQTT aus kommen. MQTT ist ja mittlerweile sehr langsam, wie der Dev von Zendure mitgeteilt hat.

                                Ok, dann legst du gar nicht so viel Wert auf die Ertragsdaten, sondern steuerst nur mit deinem Skripten?

                                Proxmox Cluster mit ioBroker, Wireguard, HomeAssistant (Testsystem), paperlessNGX, MariaDB, PiHole, Grafana, InfluxDB, 1 x BKW 600 Wp, 2 x BKW 400 Wp, 2 x SolarFlow 800 Pro mit 11,52 kWh Akku und 3,48 kWp, OpenDTU, AhoyDTU, HmIP, Shellys, AVM LAN/WLAN

                                maxclaudiM 1 Antwort Letzte Antwort
                                0
                                • C cbrocker

                                  @maxclaudi
                                  danke für die Infos.
                                  ich lese die Daten bisher auch per http request aus (zenSDK).
                                  Was macht die Funktion setDeviceAutomationInOutLimit genau? Die Funktion ist aber nur im Adapter? Also nicht von Zendure selber?

                                  Ich möchte auch ohne Adapter und ohne MQTT aus kommen. MQTT ist ja mittlerweile sehr langsam, wie der Dev von Zendure mitgeteilt hat.

                                  Ok, dann legst du gar nicht so viel Wert auf die Ertragsdaten, sondern steuerst nur mit deinem Skripten?

                                  maxclaudiM Offline
                                  maxclaudiM Offline
                                  maxclaudi
                                  schrieb am zuletzt editiert von
                                  #230

                                  @cbrocker
                                  Guten Morgen!

                                  Zu deinen Fragen: Mein Hauptskript (nicht veröffentlicht) regelt die Zendure-Geräte basierend auf dem aktuellen Zählerwert meines Hausanschlusses.

                                  Mein Setup zur Datenerfassung:
                                  Ich triggere die Regelung alle 5 Sekunden über einen UART-IR-Lesekopf am Zähler (per LAN/WT32-ETH01 angebunden).
                                  Als Backup dient ein Shelly 3 pro EM – sollte der Lesekopf keine plausiblen Werte liefern, schaltet das Skript automatisch auf den Shelly um (Failover).

                                  Statt bunter Grafiken erfasse ich die harten Fakten direkt in einer CSV-Datei und logge nur das Nötigste (Gesamtverbrauch, Einspeisung, Zählerstände).

                                  Das reicht mir völlig, um die Unversehrtheit des Systems und die realen IST-Zustände zu überwachen.
                                  Zudem bietet das CSV-file den Vorteil, dass man daraus bei Bedarf jederzeit visuelle Grafiken (z. B. mit Grafana oder Excel) erzeugen kann.

                                  Mir ist ein funktionierendes System und der reale Zählerwert wichtiger als tägliche Diagramme.
                                  Interessanter ist am Ende, was auf der Stromrechnung steht – das ist für mich KISS (Keep It Simple, Stupid).

                                  Zu MQTT & zenSDK:
                                  Du hast recht: Das von Zendure offiziell angebotene lokale MQTT ist mit Aktualisierungsraten von bis zu 90 Sekunden leider sehr langsam.

                                  Deshalb habe ich hier mein Skript für das zenSDK (HTTP) bereitgestellt.
                                  Es ist aktuell der beste Weg: Man bleibt bei der offiziellen Schnittstelle, kann App und Cloud weiterhin nutzen und ist dennoch deutlich schneller als das gedrosselte lokale MQTT.
                                  Schneller ist nur das Umbiegen der Cloud-URL (DNS-Umleitung auf lokale IP).
                                  Dann verliert man aber App und natürlich auch die Cloud, was die meisten nicht möchten.

                                  Zu setDeviceAutomationInOutLimit:
                                  Das ist eine adapterinterne Komfortfunktion und kein offizieller Bestandteil des Zendure-Systems.
                                  Soll Bedienung vereinfachen, löst aber im Hintergrund Befehlsketten aus, die für den Nutzer nicht direkt ersichtlich sind.

                                  Ich bevorzuge die volle, eigenverantwortliche Kontrolle über jeden einzelnen Befehl, basierend auf dem offiziellen Zendure-Protokoll.
                                  So weiß ich genau, was wann gesendet wird und vermeide unvorhergesehene Nebeneffekte oder unnötige Schreibvorgänge im Flash-Speicher.

                                  Jeder soll für sich entscheiden, wie viel Abstraktion oder Kontrolle er in seinem System möchte.
                                  Mehr möchte ich dazu eigentlich nicht sagen.

                                  Ich schreibe meistens sehr direkt – bitte nicht falsch verstehen, es ist nie böse gemeint. Das ist einfach mein Stil und niemals abwertend gemeint.

                                  1 Antwort Letzte Antwort
                                  0
                                  • C cbrocker

                                    Hallo,
                                    ich lese hier hin und wieder mit und habe mir auch den Adapter von nograx mal heruntergeladen, aber noch nicht wirklich eingerichtet. Bisher lese ich ein paar Daten vom SF800 per http request aus.

                                    Ich habe mal mit KI ein Script erstellen lassen, das mir den Tagesertrag anhand der laufenden PV-Produktion berechnet, aber der Wert stimmt nicht ganz mit dem in der App überein.

                                    Frage: werden im Adapter von nograx die PV-Daten (Erträge für Tag, Monat, Jahr usw.) ausgelesen oder berechnet?

                                    Danke

                                    maxclaudiM Offline
                                    maxclaudiM Offline
                                    maxclaudi
                                    schrieb am zuletzt editiert von
                                    #231

                                    @cbrocker sagte in Zendure SmartMode:1 SolarFlow2400 AC SolarFlow800 ( u. Pro):

                                    Ich habe mal mit KI ein Script erstellen lassen, das mir den Tagesertrag anhand der laufenden PV-Produktion berechnet, aber der Wert stimmt nicht ganz mit dem in der App überein.

                                    Nachtrag:
                                    Du kannst davon ausgehen, dass Dein Script genauer ist als die App-Anzeige.
                                    Anders macht das Zendure auch nicht.

                                    Es gibt mehrere keys: xxx_PowerXCycle mit entsprechenden Werten.
                                    u. a. auch für aktuelle PV-Leistung
                                    z.B.: solarPower1Cycle mit xW für MPPT1 etc.

                                    Der Mittel-Wert solarPower1Cycle dient der Aggregation von Daten für Statistiken und Diagramme

                                    Während solarPower1 (ca. Echtzeitwert) für offizielle, lokale Anbindung übertragen wird, wird solarPower1Cycle (Zykluswert/Mittelwert) ca alle 60 sek aktualisiert und nur zur Cloud übertragen.
                                    (Solange Wert-Änderungen kommen, habe ich Intervalle von 58~61 sek. geloggt.)
                                    solarPower1Cycle ist also der gemittelte oder kumulierte Wert über 60 sek.

                                    Die Zendure-Cloud nutzt diese Cycle-Werte, um die Datenbanklast zu reduzieren.
                                    Statt tausende Einzelwerte pro Tag zu speichern, werden diese 1-Minuten-Pakete genutzt, um Tages-, Monats- und Jahreserträge zu berechnen und in den App-Diagrammen darzustellen.

                                    solarPower1Cycle und andere Cycle-Werte werden (bisher) nicht bei offizieller lokaler Anbindung in properties übertragen.
                                    Nur wenn man Cloud-DNS auf lokale IP umprogrammiert oder umleitet.

                                    Ich schreibe meistens sehr direkt – bitte nicht falsch verstehen, es ist nie böse gemeint. Das ist einfach mein Stil und niemals abwertend gemeint.

                                    1 Antwort Letzte Antwort
                                    0
                                    • D Daniel 8

                                      Ergebnis war positiv heute Nacht. Er hat wie sonst auch ca. 2% verloren.

                                      Die Änderung am Script war doch nicht so einfach, weil er am unteren soc nicht abgeschaltet hat. Habe es bisschen geändert und hoffe das es so läuft.

                                      maxclaudiM Offline
                                      maxclaudiM Offline
                                      maxclaudi
                                      schrieb am zuletzt editiert von maxclaudi
                                      #232

                                      @Daniel-8 und @mabbi und Alle
                                      habe nun endlich ein neues Gerät zum testen erhalten.

                                      Dabei fiel mir gleich in meinem bisherigen Script die unübersichtliche Struktur auf.

                                      Auch beim Start gab es Warnungen, wenn erstmals neue Verzeichnisse angelegt wurden.
                                      Hat mir niemand geschrieben.

                                      Korrigiert und optimiert.

                                      Das Script ist ein vollwertiger Adpater-Ersatz.

                                      Das -1 setzen wurde entfernt.
                                      Beim setzen eines Control-State wird der Wert gesendet und gleich mit dem bestätigten Wert aktualisiert.

                                      Intervall von 8 s (für die State-Abfrage/Report) läuft mit diesem Script problemlos (Queue Sicherung), wenn Netzwerkverbindung Zendure <> WLAN-Router ok ist.

                                      MQTT (lokal) ist per Slider (boolean default deaktiviert).
                                      Wenn deaktiviert, ist die MQTT-Script-Funktion komplett ausgeschaltet:

                                      • MQTT-Intervall wird nicht ausgeführt
                                      • dadurch keine MQTT-Statusabfrage
                                      • kein Ein-/Auschalten von lokalem MQTT möglich
                                      • MQTT- Datenfelder im Kofig-Block sind dann bedeutungslos.

                                      Keine Fehler bei Start. Fehlende Verzeichnisse und Datenpunkte werden automatisch erstellt.

                                      Sollten neue Datenpunkte hinzukommen (durch Frimwareupdate) werden sie als Datenpunkte automatisch erstellt.

                                      Neue Struktur.
                                      Haupt-Verzeichnis kann im Konfigblock leicht auf einen sinnvollen, eigenen Namen geändert werden.
                                      Hinweis: wenn man auf

                                      + SN;
                                      

                                      dort verzichtet, dann ist der Verzeichnis-Name auch ohne Seriennummer des Geräts zur Unterscheidung.
                                      Die Seriennummer muss hier nicht verwendet werden, der Verzeichnis-Name muss bei mehreren Geräten aber unterschiedlich sein.

                                      Script ist erprobt. Einige keys, die mir bekannt sind, wurden unter control nicht aufgenommen, weil sie Geräte-spezifisch sind, Gefahren darstellen und/oder (noch?) nicht offiziell unterstützt werden.... wie auch immer.

                                      Bin etwas entäuscht von zenSDK.
                                      Manche keys werden von dem Zendure-Gerät-Webserver nicht oder unregelmäßig aktualisiert.

                                      Neue Struktur des Scripts:
                                      script.png

                                      minTimeBreakForSetDpSec = 5;
                                      Ist einstellbar. 5 sek. haben sich bei mir bewährt.
                                      Nach dem setzen eines Befehls müssen mindestens x sek. vergangen sein um einen neuen zu senden.

                                      Es sind mehrere Sicherungen eingebaut.
                                      Kommentare im Konfig-Bereich bitte lesen.

                                      Script ist ein Adapter-Ersatz.
                                      In meinen Augen der ehrlichste.
                                      Es werden keine Befehle und keine Befehlsketten gesendet, von denen man nichts weiß.
                                      Volle Verantwortung bei dem user.
                                      Auch smartMode wird nicht automatisch geschaltet.

                                      // ioBroker JavaScript: Zendure zenSDK Adapter-Ersatz
                                      // für alle Geräte ab 2025 die zenSDK unterstützen wie
                                      // SF800, SF800 PLUS, 800Pro, 1600AC, SF2400AC usw.
                                      // by maxclaudi 2026.03.30_19.10h for ioBroker Forum
                                      //------------------------------------------------------------------------------------
                                      // konfiguration
                                      //
                                      // Hinweis bei mehreren Zendure-Geräten:
                                      // - Für jedes Gerät ein eigenes Script mit individueller Konfiguration verwenden!
                                      //   -> IP-Adresse
                                      //   -> Seriennummer (SN)
                                      //   -> MQTT-Daten (Broker, Port, Benutzer, Passwort)
                                      //   -> maxInputLimit / maxOutputLimit (abhängig vom Gerätetyp)
                                      // - Intervalle (Standard): intervalGet = 10s, intervalMqtt = 300s – können gleich bleiben
                                      //
                                      // Empfehlung:
                                      //   • 3 Geräte: völlig unkritisch
                                      //   • 4 Geräte: problemlos möglich
                                      //   • mehr als 4: nicht empfohlen
                                      //
                                      // MQTT-Abfrage ist per default false=disabled. Lokales, offizielles MQTT ist mit bis zu 90sek Aktualisierungsrate zu langsam.
                                      // Empfehle zenSDK zu verwenden oder DNS auf lokalen Betrieb umzubiegen.
                                      // Wer offizielles, lokale MQTT dennoch benutzen möchte und überwachen möchte kann den Datenpunkt mit dem Slider einschalten.
                                      // Satndardist bei script-Start MQTT-Abfrage ausgeschaltet und wird dann vom script komplett deaktiviert.
                                      // Auch kein Intervall und keine Aktualisierung erfolgt dann.
                                      //
                                      // Damit neue Datenpunkte automatisch aus dem JSON erstellt werden:
                                      // -> Instanzen -> javascript-Adapter -> Allgemeine Einstellungen -> Enable command"setObject“ aktivieren!
                                      //
                                      // Datenpunkte bei set werden automatisch aktualisiert und nicht auf -1 zurück gesetzt.
                                      //------------------------------------------------------------------------------------
                                      
                                      //------------------------------------------------------------------------------------
                                      // CONFIG
                                      //------------------------------------------------------------------------------------
                                      // Intervalle für Abfragen (Sekunden)
                                      const intervalGet = 8;                  // sek Intervall für GET report (default: 8, nicht <8) intervalGet MUSS größer sein als timeoutHttp !!
                                      const intervalMqtt = 300;                // sek MQTT-Status (default: 300 sek, > intervalGet) wird nur ausgeführt wenn Abfrage über SetMqttEnable eingeschaltet wird.
                                      
                                      // IP und Seriennummer Zendure Gerät
                                      const IP = "192.168.40.20";              // IP des Zendure Geräts
                                      const SN = "Exxxxxxxxxxx007";            // Seriennummer
                                                   
                                      // MQTT Broker Konfiguration
                                      const mqttBrokerIp = "192.168.40.200";  // IP MQTT Broker und in App eingestellt 
                                      const mqttPort = 1883;                  // PORT MQTT Broker und in App eingestellt           
                                      const mqttUsername = "Daisy";           // MQTT Username
                                      const mqttPassword = "coco";            // MQTT Passwort
                                      
                                      //maximum inputLimit SF800 800W / SF800 PRO: 1000W / 1600AC: 1600 / SF2400AC: 2400W
                                      const maxInputLimit = 1000;
                                      
                                      //maximum outputLimit SF800 800W / SF800 PRO: 800W / 1600AC: 1600 / SF2400AC: 2400W
                                      const maxOutputLimit = 800;
                                      
                                      // Pause (Wert in Sekunden) die vergangen sein muss bevor ein neuer Befehl gesendet werden kann.
                                      const minTimeBreakForSetDpSec = 5; // 5 s hat sich bei mir bewährt, minimal 2s!
                                      
                                      // Haupt-Verzeichnis für das Zendure-Gerät
                                      // hier kann der Name für das Hauptverzeichnis für das Gerät verändert werden.
                                      // Standard wird die Seriennummer verwendet. Es kann aber durch einen beliebigen Namen ersetzt werden.
                                      // Beispiel:
                                      //const folderZendureApi = '0_userdata.0.zendure.' + "SolarFlow_800_1_Dachboden_links";
                                      const folderZendureApi = '0_userdata.0.zendure.' + SN;
                                      //
                                      // Timout Handler HTTP GET /POST
                                      // timeoutHttp MUSS kleiner sein als intervalGet!! Besser nicht ändern. Standard: 2000ms
                                      const timeoutHttp = 2000; // Timeout in ms für alle HTTP-Anfragen (Zendure)
                                      //------------------------------------------------------------------------------------
                                      // End of config
                                      //------------------------------------------------------------------------------------
                                      
                                      const mqttStateAskingDefault = false; // nicht verändern! Kann bei laufendem script ein- oder ausgeschaltet werden
                                      let lastMqttSet = 0;
                                      let mqttInterval = null;
                                      
                                      //------------------------------------------------------------------------------------
                                      // dp
                                      //------------------------------------------------------------------------------------
                                      
                                      const dpSetSmartMode        = folderZendureApi + ".control.setSmartMode";
                                      const dpSetAcMode           = folderZendureApi + ".control.setAcMode";
                                      const dpSetInputLimit       = folderZendureApi + ".control.setInputLimit";
                                      const dpSetOutputLimit      = folderZendureApi + ".control.setOutputLimit";
                                      const dpSetSocSet           = folderZendureApi + ".control.setSocSet";
                                      const dpSetMinSoc           = folderZendureApi + ".control.setMinSoc";
                                      const dpSetGridReverse      = folderZendureApi + ".control.setGridReverse";
                                      const dpSetGridStandard     = folderZendureApi + ".control.setGridStandard";
                                      const dpSetInverseMaxPower  = folderZendureApi + ".control.setInverseMaxPower";
                                      const dpSetChargeMaxLimit   = folderZendureApi + ".control.setChargeMaxLimit";
                                      const dpSetGridOffMode      = folderZendureApi + ".control.setGridOffMode";
                                      
                                      const dpSetMqttEnable       = folderZendureApi + ".control.localMqtt.EnableScriptControlLocalMqtt";
                                      const dpSetMqttConnect      = folderZendureApi + ".control.localMqtt.SetConnectlocalMqtt";
                                      const dpMqttConnectInfo     = folderZendureApi + ".control.localMqtt.InfoLocalMqttConnected";
                                      
                                      const dpTimestamp           = folderZendureApi + ".timestamp";
                                      
                                      //------------------------------------------------------------------------------------
                                      // mapping
                                      //------------------------------------------------------------------------------------
                                      const dpMap = {
                                          [dpSetSmartMode]:       { key: "smartMode", min: 0, max: 1 },
                                          [dpSetAcMode]:          { key: "acMode", min: 1, max: 2 },
                                          [dpSetInputLimit]:      { key: "inputLimit", min: 0, max: maxInputLimit },
                                          [dpSetOutputLimit]:     { key: "outputLimit", min: 0, max: maxOutputLimit },
                                          [dpSetSocSet]:          { key: "socSet", transform: v => v*10, min: 70, max: 100 },
                                          [dpSetMinSoc]:          { key: "minSoc", transform: v => v*10, min: 5, max: 50 },
                                          [dpSetGridReverse]:     { key: "gridReverse", min: 0, max: 2 },
                                          [dpSetGridStandard]:    { key: "gridStandard", min: 0, max: 2 },
                                          [dpSetInverseMaxPower]: { key: "inverseMaxPower", min: 600, max: maxOutputLimit },
                                          [dpSetChargeMaxLimit]:  { key: "chargeMaxLimit", min: 0, max: maxInputLimit },
                                      	[dpSetGridOffMode]:     { key: "gridOffMode", min: 0, max: 2 }
                                      };
                                      
                                      //------------------------------------------------------------------------------------
                                      // QUEUE
                                      //------------------------------------------------------------------------------------
                                      const curlQueue = [];
                                      let curlRunning = false;
                                      
                                      function runQueue() {
                                          if (curlRunning || curlQueue.length === 0) return;
                                          const task = curlQueue.shift();
                                          curlRunning = true;
                                          task.fn(() => {
                                              curlRunning = false;
                                              runQueue();
                                          });
                                      }
                                      
                                      //------------------------------------------------------------------------------------
                                      // helper
                                      //------------------------------------------------------------------------------------
                                      function delay(ms) {
                                          return new Promise(resolve => setTimeout(resolve, ms));
                                      }
                                      
                                      function formatTime(ts) {
                                          const d = new Date(ts * 1000);
                                          const pad = n => n.toString().padStart(2, "0");
                                          return `${pad(d.getDate())}.${pad(d.getMonth()+1)}.${d.getFullYear().toString().slice(-2)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
                                      }
                                      
                                      function handleHttpError(context, err, options) {
                                      	const transient = [
                                              "EHOSTUNREACH", "ECONNRESET", "ECONNREFUSED", "ETIMEDOUT",
                                              "socket hang up", "ENETUNREACH", "EAI_AGAIN", "ENOTFOUND"
                                          ];
                                      	
                                      	const msg = err && err.message ? err.message : String(err);
                                          const isTransient = transient.some(code => msg.includes(code));
                                       
                                          //info_error
                                      	//log(`${context}: ${isTransient ? "war vorübergehend im Intervall nicht erfolgreich:" : "Warnung"} (${msg})`, isTransient ? "info" : "warn");
                                          log(`${context}: ${isTransient ? "war vorübergehend im Intervall nicht erfolgreich:" : "Warnung"} (${msg})`, "info");
                                       
                                          // set Timestamp
                                          if (options && options.timestamp) {
                                              setState(options.timestamp, formatTime(Math.floor(Date.now() / 1000)), true);
                                          }
                                      }
                                      
                                      //------------------------------------------------------------------------------------
                                      // CREATE STATES
                                      //------------------------------------------------------------------------------------
                                      const dataPoints = [
                                          { id: dpSetSmartMode, val: 0, common: { name: "Smart Mode 0:FLASH 1:RAM",desc: "Flash write behavior", type: "number", role: "state", min: 0, max: 1 } },
                                          { id: dpSetAcMode, val: 1, common: { name: "AC Mode 1:charge mode 2:discharge mode", type: "number", role: "state", min: 1, max: 2 } },
                                          { id: dpSetInputLimit, val: 0, common: { name: "Input Limit AC charge limit", type: "number", role: "state", min: 0, max: maxInputLimit, unit: 'W' } },
                                          { id: dpSetOutputLimit, val: 0, common: { name: "Output Limit", type: "number", role: "state", min: 0, max: maxOutputLimit, unit: 'W' } },
                                          { id: dpSetSocSet, val: 70, common: { name: "SOC Set (Target SOC 70%-100%)", type: "number", role: "state", min: 70, max: 100, unit: '%' } },
                                          { id: dpSetMinSoc, val: 5, common: { name: "Min SOC (Minimum SOC 5%-50%)", type: "number", role: "state", min: 5, max: 50, unit: '%' } },
                                          { id: dpSetGridReverse, val: 0, common: { name: "Reverse flow control (0/1/2)", type: "number", role: "state", min: 0, max: 2 } },
                                          { id: dpSetGridStandard, val: 0, common: { name: "Grid Standard (0: Germany 1: France 2: Austria...)", desc: "(3: Switzerland 4: Netherlands 5: Spain 6: Belgium 7: Greece 8: Denmark 9: Italy)", type: "number", role: "state", min: 0, max: 9 } },
                                          { id: dpSetInverseMaxPower, val: 600, common: { name: "Max inverter output Power", type: "number", role: "state", min: 600, max: maxOutputLimit, unit: 'W' } },
                                          { id: dpSetChargeMaxLimit, val: 0, common: { name: "Charge Max Limit", type: "number", role: "state", min: 0, max: maxInputLimit, unit: 'W' } },
                                      	{ id: dpSetGridOffMode, val: 0, common: { name: "Grid Off Mode 0: Standard Mode  1: Economic Mode  2: Closure", type: "number", role: "state", min: 0, max: 2 } },
                                      	{ id: dpSetMqttEnable, val: mqttStateAskingDefault, common: { name: "Enable Script-Control of Local Mqtt: Off ON", type: "boolean", role: "state", read: true, write: true } },
                                          { id: dpSetMqttConnect, val: 0, common: { name: "Set Connect localMqtt -> only if EnableScriptControlLocalMqtt: on", type: "number", role: "indicator", read: true, write: true } },
                                          { id: dpMqttConnectInfo, val: 0, common: { name: "Info Local Mqtt Connected 0:off 1:on -> only if EnableScriptControlLocalMqtt: on", type: "number", role: "indicator", read: true, write: false } },
                                          { id: dpTimestamp, val: "", common: { name: "Timestamp", type: "string", role: "state", read: true, write: false } }
                                      ];
                                      
                                      async function startScript() {
                                          console.log("Erstelle Datenpunkte...");
                                          for (const dp of dataPoints) {
                                              await createStateAsync(dp.id, dp.val, dp.common);
                                          }
                                          
                                          setState(dpSetMqttEnable, mqttStateAskingDefault, true);
                                          console.log("Datenpunkte bereit. Starte Abfragen...");
                                          setInterval(getReport, intervalGet * 1000);
                                          getReport(); 
                                      }
                                      
                                      startScript();
                                      
                                      
                                      //------------------------------------------------------------------------------------
                                      // TRIGGERS (SET)
                                      //------------------------------------------------------------------------------------
                                      Object.keys(dpMap).forEach(id => {
                                          let lastSetTime = 0;
                                      
                                          on({ id: id, ack: false }, obj => {
                                              const val = obj.state.val;
                                              const { min, max } = dpMap[id];
                                      
                                              if (val >= min && val <= max) {
                                                  const now = Date.now();
                                                  if (now - lastSetTime >= minTimeBreakForSetDpSec * 1000) {
                                                      lastSetTime = now;
                                                      setControlDP(id, val);
                                                  }
                                              }
                                          });
                                      });
                                      
                                      // MQTT POST nur wenn enable=true + rate limit
                                      on({ id: dpSetMqttConnect, ack: false }, obj => {
                                      
                                          if (!getState(dpSetMqttEnable).val) return;
                                      
                                          const now = Date.now();
                                          if (now - lastMqttSet < minTimeBreakForSetDpSec * 1000) return;
                                      
                                          lastMqttSet = now;
                                      
                                          const val = parseInt(obj.state.val, 10);
                                          if (val === 0 || val === 1) setMqttConnect(val);
                                      });
                                      
                                      //------------------------------------------------------------------------------------
                                      // HTTP
                                      //------------------------------------------------------------------------------------
                                      const http = require("http");
                                      
                                      function setControlDP(id, val) {
                                          const { key, transform } = dpMap[id];
                                          const value = transform ? transform(val) : val;
                                      
                                          curlQueue.push({
                                              fn: done => {
                                                  const payload = JSON.stringify({ sn: SN, properties: { [key]: value } });
                                      
                                                  const req = http.request({
                                                      hostname: IP,
                                                      port: 80,
                                                      path: "/properties/write",
                                                      method: "POST",
                                                      headers: { 
                                                          "Content-Type": "application/json", 
                                                          "Content-Length": Buffer.byteLength(payload) 
                                                      }
                                                  }, res => {
                                                      res.on("data", () => {});
                                                      res.on("end", () => {
                                                          // nach Schreiben sofort anfordern
                                                          curlQueue.unshift({ fn: d => getReportInternal(d) });
                                                          done(); // freigeben
                                                      });
                                                  });
                                      
                                                  // Timeout
                                                  req.setTimeout(timeoutHttp, () => {
                                                      req.destroy(); // Verbindung hart abbrechen
                                                      handleHttpError("POST Timeout", "Gerät antwortet nicht", { timestamp: dpTimestamp });
                                                      done(); // WICHTIG: Queue freigeben, damit nächste Befehle folgen können
                                                  });
                                      
                                                  // Fehler
                                                  req.on("error", err => { 
                                                      handleHttpError("POST Error", err, { timestamp: dpTimestamp }); 
                                                      done();
                                                  });
                                      
                                                  req.write(payload);
                                                  req.end();
                                              }
                                          });
                                      
                                          runQueue();
                                      }
                                      
                                      
                                      function getReport() {
                                          curlQueue.push({ fn: done => getReportInternal(done) });
                                          runQueue();
                                      }
                                      
                                      function getReportInternal(done) {
                                          const req = http.request({
                                              hostname: IP,
                                              port: 80,
                                              path: "/properties/report",
                                              method: "GET"
                                          }, res => {
                                              let data = "";
                                              res.on("data", chunk => data += chunk);
                                              res.on("end", async () => {
                                                  try {
                                                      const json = JSON.parse(data);
                                                      if (json.properties) {
                                                          Object.keys(dpMap).forEach(dp => {
                                                              const { key } = dpMap[dp];
                                                              if (json.properties[key] !== undefined) {
                                                                  setState(dp, json.properties[key], true);
                                                              }
                                                          });
                                                      }
                                                      setState(dpTimestamp, formatTime(Math.floor(Date.now()/1000)), true);
                                                      await processJson(json);
                                                  } catch (e) {
                                                      log("GET parse error: " + e, "info");
                                                  }
                                                  done(); // WICHTIG: Queue freigeben nach Erfolg
                                              });
                                          });
                                      
                                          
                                          // Fehler
                                          req.on("error", err => { 
                                              handleHttpError("GET Error", err, { timestamp: dpTimestamp }); 
                                              done(); // WICHTIG: Queue freigeben bei Fehler
                                          });
                                      
                                          // Timeout
                                          req.setTimeout(timeoutHttp, () => {
                                              req.destroy(); // Verbindung abbrechen
                                              handleHttpError("GET Timeout", "Gerät antwortet nicht", { timestamp: dpTimestamp });
                                              done(); // WICHTIG: Queue freigeben bei Zeitüberschreitung
                                          });
                                          req.end();
                                      }
                                      
                                      //------------------------------------------------------------------------------------
                                      // MQTT
                                      //------------------------------------------------------------------------------------
                                      
                                      // Enable-Schalter nur Steuerung, kein POST
                                      on({ id: dpSetMqttEnable, ack: false }, obj => {
                                      
                                          const enable = !!obj.state.val;
                                          setState(dpSetMqttEnable, enable, true);
                                      
                                          if (enable) {
                                      
                                              // sofort GET
                                              curlQueue.push({ fn: d => getMqttStatusInternal(d) });
                                              runQueue();
                                      
                                              // Intervall start
                                              if (!mqttInterval) {
                                                  mqttInterval = setInterval(() => {
                                                      curlQueue.push({ fn: d => getMqttStatusInternal(d) });
                                                      runQueue();
                                                  }, intervalMqtt * 1000);
                                              }
                                      
                                          } else {
                                      
                                              if (mqttInterval) {
                                                  clearInterval(mqttInterval);
                                                  mqttInterval = null;
                                              }
                                          }
                                      });
                                      
                                      function getMqttStatusInternal(done) {
                                      
                                          const req = http.request({
                                              hostname: IP,
                                              port: 80,
                                              path: "/rpc?method=HA.Mqtt.GetStatus",
                                              method: "GET"
                                          }, res => {
                                      
                                              let data = "";
                                      
                                              res.on("data", chunk => data += chunk);
                                      
                                              res.on("end", () => {
                                      
                                                  try {
                                                      const json = JSON.parse(data);
                                                      const state = json.connected ? 1 : 0;
                                      
                                                      // readonly
                                                      setState(dpMqttConnectInfo, state, true);
                                      
                                                      // sync setDP (OHNE trigger)
                                                      setState(dpSetMqttConnect, state, true);
                                      
                                                  } catch (e) {
                                                      log("MQTT parse error: " + e, "info");
                                                  }
                                      
                                                  done();
                                              });
                                          });
                                      
                                          req.on("error", err => { handleHttpError("MQTT GET", err, { timestamp: dpTimestamp }); done(); });
                                      
                                          req.end();
                                      }
                                      
                                      function setMqttConnect(enable) {
                                      
                                          const payload = JSON.stringify({
                                              sn: SN,
                                              method: "HA.Mqtt.SetConfig",
                                              params: {
                                                  config: {
                                                      enable: !!enable,
                                                      server: mqttBrokerIp,
                                                      port: mqttPort,
                                                      protocol: "mqtt",
                                                      username: mqttUsername,
                                                      password: mqttPassword
                                                  }
                                              }
                                          });
                                      
                                          curlQueue.push({
                                              fn: done => {
                                      
                                                  const req = http.request({
                                                      hostname: IP,
                                                      port: 80,
                                                      path: "/rpc",
                                                      method: "POST",
                                                      headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(payload) }
                                                  }, res => {
                                                      res.on("data", () => {});
                                                      res.on("end", () => done());
                                                  });
                                      
                                                  req.on("error", err => { handleHttpError("MQTT POST", err, { timestamp: dpTimestamp }); done(); });
                                      
                                                  req.write(payload);
                                                  req.end();
                                              }
                                          });
                                      
                                          runQueue();
                                      }
                                      
                                      //------------------------------------------------------------------------------------
                                      // JSON
                                      //------------------------------------------------------------------------------------
                                      async function processJson(obj) {
                                          try {
                                              if (!obj || !obj.product) return;
                                       
                                              const product = obj.product;
                                              const basePath = `${folderZendureApi}.${product}`;
                                       
                                              // create product folder if not exist
                                              if (!existsObject(basePath)) {
                                                  setObject(basePath, {
                                                      type: 'folder',
                                                      common: { name: product },
                                                      native: {},
                                                  });
                                              }
                                       
                                              // create main keys
                                              const mainKeys = ['timestamp', 'messageId', 'sn', 'version', 'product'];
                                              for (const key of mainKeys) {
                                                  if (obj[key] !== undefined) {
                                                      const statePath = `${basePath}.${key}`;
                                                      if (existsState(statePath)) {
                                                          setState(statePath, obj[key], true);
                                                      } else {
                                                          createState(statePath, obj[key], {
                                                              name: key,
                                                              type: typeof obj[key],
                                                              role: 'info',
                                                              read: true,
                                                              write: false,
                                                          });
                                                      }
                                                  }
                                              }
                                       
                                              // properties
                                              if (obj.properties) {
                                                  await iter(`${basePath}.properties`, obj.properties);
                                              }
                                       
                                              // PackData
                                              if (obj.packData && Array.isArray(obj.packData)) {
                                                  await iter(`${basePath}`, { packData: obj.packData, timestamp: obj.timestamp });
                                              }
                                          } catch (e) {
                                              log(`Error processing JSON: ${e}`, 'info');
                                          }
                                      }
                                       
                                      //------------------------------------------------------------------------------------
                                      // Battery
                                      //------------------------------------------------------------------------------------
                                      function getBatteryType(sn, model) {
                                        let batType = '';
                                        if (sn?.startsWith('A')) batType = 'AB1000';
                                        else if (sn?.startsWith('B')) batType = 'AB1000S';
                                        else if (sn?.startsWith('C')) batType = sn[3] === 'F' ? 'AB2000S' : sn[3] === 'E' ? 'AB2000X' : 'AB2000';
                                        else if (sn?.startsWith('F')) batType = 'AB3000X';
                                        if (model?.trim()) batType = model.trim();
                                        return batType || 'unknown';
                                      } 
                                       
                                      //------------------------------------------------------------------------------------
                                      // helper Iteration
                                      //------------------------------------------------------------------------------------
                                      async function iter(id, obj) {
                                          try {
                                      		if (!obj || typeof obj !== "object") {
                                                 //log("iter: Ungültiges oder leeres Objekt übersprungen", "info");
                                                 return;
                                                 }
                                      		for (let i in obj) {
                                                  if (i === 'packData' && Array.isArray(obj[i])) {
                                                      const ts = obj.timestamp ? obj.timestamp * 1000 : Date.now();
                                                      for (const pack of obj[i]) {
                                                          if (!pack.sn) continue;
                                                          const sn = pack.sn;
                                                          const path = `${id}.packData.${sn}`;
                                       
                                                          if (!existsObject(path)) {
                                                              setObject(path, {
                                                                  type: 'folder',
                                                                  common: { name: sn },
                                                                  native: {},
                                                              });
                                                          }
                                       
                                                          for (let [key, val] of Object.entries(pack)) {
                                                              const statePath = `${path}.${key}`;
                                                              switch (key) {
                                                                  case 'batcur':
                                                                      val = (val << 16 >> 16) / 10;
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);;
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Battery Current',
                                                                              type: 'number',
                                                                              desc: 'battery current',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                              unit: 'A',
                                                                          });
                                                                      }
                                                                      break;
                                      							case 'heatState':
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Heat State, 0: Not heating, 1: heating',
                                                                              type: 'number',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                          });
                                                                      }
                                                                      break;		
                                      							case 'maxTemp':
                                                                      val = (val - 2731) / 10;
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Highest Akku Temperature',
                                                                              type: 'number',
                                                                              desc: 'maximum temperature',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                              unit: '°C',
                                                                          });
                                                                      }
                                                                      break;
                                                                  case 'maxVol':
                                                                      val = val / 100;
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Highest Cell Voltage',
                                                                              type: 'number',
                                                                              desc: 'highest cell voltage',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                              unit: 'V',
                                                                          });
                                                                      }
                                                                      break;
                                                                  case 'minVol':
                                                                      val = val / 100;
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Lowest Cell Voltage',
                                                                              type: 'number',
                                                                              desc: 'lowest cell voltage',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                              unit: 'V',
                                                                          });
                                                                      }
                                                                      break;
                                      							case 'packType':
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'packType',
                                                                              type: 'number',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                          });
                                                                      }
                                                                      break;
                                      							case 'power':
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Battery Power',
                                                                              type: 'number',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                              unit: 'W',
                                                                          });
                                                                      }
                                      								break;
                                      							case 'sn':
                                                                  const batType = getBatteryType(val, pack.model);
                                                                  // Modelltyp als Datenpunkt setzen/erstellen
                                                                  const modelPath = `${path}.model`;
                                                                  if (existsState(modelPath)) {
                                      								setState(modelPath, batType, true);
                                                                      } else {
                                                                          createState(modelPath, batType, {
                                                                          name: 'Battery Model',
                                                                          type: 'string',
                                                                          role: 'text',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                         }
                                                                      break;
                                      							case 'socLevel':
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Battery SoC Level',
                                                                              type: 'number',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                              unit: '%',
                                                                          });
                                                                      }
                                      								break;
                                      							case 'softVersion':
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Battery Software Version',
                                                                              type: 'number',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                          });
                                                                      }
                                      								break;
                                      							case 'state':
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Battery, 0: Standby, 1: Charging, 2: Discharging',
                                                                              type: 'number',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                          });
                                                                      }
                                      								break;	
                                                                  case 'totalVol':
                                                                      val = val / 100;
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: 'Total Voltage',
                                                                              type: 'number',
                                                                              desc: 'total voltage',
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                              unit: 'V',
                                                                          });
                                                                      }
                                                                      break;
                                                                  default:
                                                                      if (existsState(statePath)) {
                                                                          setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                              name: key,
                                                                              type: typeof val,
                                                                              role: 'value',
                                                                              read: true,
                                                                              write: false,
                                                                          });
                                                                      }
                                                                      break;
                                                              }
                                                          }
                                                      }
                                                  } else {
                                                      const ts = Date.now();
                                                      const statePath = `${id}.${i}`;
                                                      let val = obj[i];
                                       
                                                      switch (i) {
                                                          case 'BatVolt':
                                                              val = val / 100;
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'Battery Voltage',
                                                                      type: 'number',
                                                                      desc: 'battery voltage',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                      unit: 'V',
                                                                  });
                                                              }
                                                              break;
                                      					case 'chargeMaxLimit':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'maximum Charge Power Limit',
                                                                      type: 'number',
                                                                      desc: 'Maximum permissible charging power',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                      unit: 'W',
                                                                  });
                                                              }
                                                              break;
                                                          case 'acMode':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'acMode, 1: input mode / 2: output mode',
                                                                      type: 'number',
                                                                      desc: '1: charging / 2: discharging',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                  });
                                                              }
                                                              break;
                                      					case 'dataReady':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'Data Ready, 0: Not ready, 1: Ready',
                                                                      type: 'number',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                  });
                                                              }
                                                              break;	
                                      					case 'dcStatus':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'dcStatus, 0: Stopped, 1: Battery input, 2: Battery output',
                                                                      type: 'number',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                  });
                                                              }
                                                              break;						
                                      					case 'electricLevel':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'Total Battery Charge Level',
                                                                      type: 'number',
                                                                      desc: 'SoC',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                      unit: '%',
                                                                  });
                                                              }
                                                              break;
                                      					case 'FMVolt':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'Voltage activation value',
                                                                      type: 'number',
                                                                      desc: 'SoC',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                      unit: 'V',
                                                                  });
                                                              }
                                                              break;
                                                          case 'gridInputPower':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'Grid Input Power to Battery',
                                                                      type: 'number',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                      unit: 'W',
                                                                  });
                                                              }
                                                              break;
                                                          case 'gridReverse':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: '0: Disabled, 1: Allowed reverse flow, 2: Forbidden reverse flow',
                                                                      type: 'number',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                  });
                                                              }
                                                              break;
                                                          case 'gridStandard':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'Grid connection standard 0: Germany 1: France 2: Austria',
                                                                      type: 'number',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                  });
                                                              }
                                                              break;
                                                          case 'gridState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'Grid connection state, 0: Not connected, 1: Connected',
                                                                      type: 'number',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                  });
                                                              }
                                                              break;									
                                                          case 'heatState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: 'Heat State, 0: Not heating, 1: heating',
                                                                      type: 'number',
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                  });
                                                              }
                                                              break;		
                                      					case 'hyperTmp':
                                                              val = (val - 2731) / 10.0;
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Enclosure Temperature',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          unit: '°C',
                                                                          });
                                                                      }
                                                              break;
                                      					case 'inputLimit':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'AC charging power limit to Battery',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                      					case 'inverseMaxPower': 
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Max inverter output Power Limit',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                      					case 'minSoc':
                                                              val = val / 10;
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'min SoC',
                                                                          type: 'number',
                                                                          desc: 'minimum Battery SoCset',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          unit: '%',
                                                                          });
                                                                      }
                                                              break;
                                      					case 'outputHomePower':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'outputHomePower',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      							        unit: 'W',
                                                                          });
                                      								}
                                                              break;
                                      					case 'outputLimit':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'Output power limit',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      							        unit: 'W',
                                                                          });
                                      								}
                                                              break;
                                      					case 'outputPackPower':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'Output power to battery pack (charging)',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      							        unit: 'W',
                                                                          });
                                      								}
                                                              break;
                                      					case 'packInputPower':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'Battery pack input power (discharging)',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      							        unit: 'W',
                                                                          });
                                      								}
                                                              break;
                                      					case 'packNum':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'Number of battery packs',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                      								}
                                                              break;
                                      					case 'packState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'Battery State, 0: Standby, 1: Charging, 2: Discharging',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                      								}
                                                              break;
                                      					case 'pass':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'Bypass, 0: No, 1: Yes',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                      								}
                                                              break;
                                      					case 'pvStatus':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'PV State producing, 0: Stopped, 1: Running',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                      								}
                                                              break;
                                                          case 'acStatus':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'AC state 0-2',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                      								}
                                                              break;							
                                      					case 'remainOutTime':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'Estimated discharge time in minutes, if not predictable: 59940',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'min',
                                                                          });
                                      								}
                                                              break;		
                                      					case 'reverseState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'Reverse flow, 0: No, 1: Reverse flow',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                      								}
                                                              break;			
                                      					case 'rssi':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: 'Received Signal Strength Indicator',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'dBm',
                                                                          });
                                      								}
                                                              break;
                                      					case 'gridOffPower':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Off-grid power',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                      					case 'lampSwitch':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Lamp state 0:off 1:on',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'gridOffMode':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Off-grid mode',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'IOTState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'IoT connection',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'fanSwitch':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Fan state 0:off 1:on',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'fanSpeed':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Fan level',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'faultLevel':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Fault severity',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'bindstate':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Bind state',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'VoltWakeup':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Voltage wake-up',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'OldMode':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Legacy mode',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'OTAState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'OTA state',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'LCNState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'LCN state',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'factoryModeState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Phase switch',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'phaseSwitch':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Factory mode',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'is_error':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Error flag 0: no Error  1: Error',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'smartMode':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                      									createState(statePath, val, {
                                                                          name: '1: parameter written to RAM / 0: parameter is written to flash.',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                      								}
                                                              break;		
                                      					case 'socLimit':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'socLimit-Info 0: normal, 1: Charge limit reached, 2: Discharge limit reached',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'socSet':
                                                              val = val / 10;
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'max SoC',
                                                                          type: 'number',
                                                                          desc: 'maximum Battery SoCset',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          unit: '%',
                                                                          });
                                                                      }
                                                              break;
                                      					case 'socStatus':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Info of Calibrating, 0: No / 1: Calibrating',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'solarInputPower':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Total Solar Input Power',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                                          case 'solarPower1':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Solar line 1 input power',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                                          case 'solarPower2':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Solar line 2 input power',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                                          case 'solarPower3':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Solar line 3 input power',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                                          case 'solarPower4':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Solar line 4 input power',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                                          case 'solarPower5':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Solar line 5 input power',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                                          case 'solarPower6':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Solar line 6 input power',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                      									unit: 'W',
                                                                          });
                                                                      }
                                                              break;
                                      					case 'timeZone':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Timezone',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'tsZone':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Timezone offset',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                      					case 'acCouplingState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                      									name: 'AC Coupling State',
                                      									type: 'number',
                                      									role: 'value',
                                      									read: true,
                                      									write: false
                                      									});
                                                                      }
                                      						let states = [];
                                      						if (val & (1 << 0)) states.push("AC-coupled input present");
                                      						if (val & (1 << 1)) states.push("AC input present flag");
                                      						if (val & (1 << 2)) states.push("AC-coupled overload");
                                      						if (val & (1 << 3)) states.push("Excess AC input power");
                                      						const statusText = states.length > 0 ? states.join(", ") : "Normal / No Flags";
                                      						const stringPath = statePath + "_String"; // acCouplingState_String
                                      						if (existsState(stringPath)) {
                                      						setState(stringPath, statusText, true);
                                      						} else {
                                      							createState(stringPath, statusText, { name: 'AC Coupling State Info', type: 'string', role: 'text', read: true, write: false });
                                      						}
                                      					break;
                                      					case 'dryNodeState':
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                                      } else {
                                                                          createState(statePath, val, {
                                                                          name: 'Dry contact status 1: Connected 0: Connected(May be reversed depending on actual wiring)',
                                                                          type: 'number',
                                                                          role: 'value',
                                                                          read: true,
                                                                          write: false,
                                                                          });
                                                                      }
                                                              break;
                                                          case 'timestamp':
                                                              const timestampVal = obj[i];
                                                              const timestampFormatted = formatTime(timestampVal);
                                                              if (existsState(statePath)) setState(statePath, timestampVal, true);
                                                              else createState(statePath, timestampVal, {
                                                                  name: 'System timestamp',
                                                                  type: 'number',
                                                                  desc: 'unix timestamp in Seconds since Jan 01 1970 (UTC)',
                                                                  role: 'value',
                                                                  read: true,
                                                                  write: false,
                                                              });
                                                              if (existsState(id + '.timeUpdateTimestamp')) setState(id + '.timeUpdateTimestamp', timestampFormatted, true);
                                                              else createState(id + '.timeUpdateTimestamp', timestampFormatted, {
                                                                  name: 'TimeUpdate (timestamp)',
                                                                  type: 'string',
                                                                  desc: 'unix timestamp in readable Format (timestamp)',
                                                                  read: true,
                                                                  write: false,
                                                              });
                                                              break;
                                                          case 'ts':
                                                              const tsVal = obj[i];
                                                              const tsFormatted = formatTime(tsVal);
                                                              if (existsState(statePath)) setState(statePath, tsVal, true);
                                                              else createState(statePath, tsVal, {
                                                                  name: 'Unix timestamp (ts)',
                                                                  type: 'number',
                                                                  desc: 'unix timestamp in Seconds since Jan 01 1970 (UTC)',
                                                                  role: 'value',
                                                                  read: true,
                                                                  write: false,
                                                              });
                                                              if (existsState(id + '.timeUpdateTs')) setState(id + '.timeUpdateTs', tsFormatted, true);
                                                              else createState(id + '.timeUpdateTs', tsFormatted, {
                                                                  name: 'TimeUpdate (ts)',
                                                                  type: 'string',
                                                                  desc: 'unix timestamp in readable Format (ts)',
                                                                  read: true,
                                                                  write: false,
                                                              });
                                                              break;			
                                                          default:
                                                              if (existsState(statePath)) {
                                                                  setState(statePath, val, true);
                                                              } else {
                                                                  createState(statePath, val, {
                                                                      name: i,
                                                                      type: typeof val,
                                                                      role: 'value',
                                                                      read: true,
                                                                      write: false,
                                                                  });
                                                              }
                                                              break;
                                                      }
                                                  }
                                              }
                                          } catch (e) {
                                              log(`Error in iter: ${e}`, 'info');
                                          }
                                      }
                                      
                                      

                                      Euch allen viel Sonne und weiterhin viel Freude.

                                      Ich schreibe meistens sehr direkt – bitte nicht falsch verstehen, es ist nie böse gemeint. Das ist einfach mein Stil und niemals abwertend gemeint.

                                      1 Antwort Letzte Antwort
                                      0

                                      Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.

                                      Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.

                                      Mit deinem Input könnte dieser Beitrag noch besser werden 💗

                                      Registrieren Anmelden
                                      Antworten
                                      • In einem neuen Thema antworten
                                      Anmelden zum Antworten
                                      • Älteste zuerst
                                      • Neuste zuerst
                                      • Meiste Stimmen


                                      Support us

                                      ioBroker
                                      Community Adapters
                                      Donate

                                      587

                                      Online

                                      32.7k

                                      Benutzer

                                      82.6k

                                      Themen

                                      1.3m

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

                                      • Du hast noch kein Konto? Registrieren

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