Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Hardware
    4. SONOFF NSPanel mit Lovelace UI

    NEWS

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    • Minor js-controller 7.0.7 Update in latest repo

    SONOFF NSPanel mit Lovelace UI

    This topic has been deleted. Only users with topic management privileges can see it.
    • R
      ronny130286 @Armilar last edited by ronny130286

      @armilar

      Sorry:)
      Ich habe halt durch den Neubau keine Wechsel/Kreuzschaltung etc im Haus verbaut sondern reinweg Taster.

      Bei mir geht jeder Taster in den Schaltschrank und von dort aus zum Licht. Ich kann auch jeden Schalter umprogrammieren, wenn er ein andere Licht schalten soll;)

      Alle Schaltwippen habe immer die gleiche Stellung (optikhalber).

      Bin gelernter Automatisierungselektroniker:)

      1 Reply Last reply Reply Quote 0
      • Armilar
        Armilar Most Active Forum Testing last edited by

        @ronny130286 sagte in SONOFF NSPanel mit Lovelace UI:

        Bin gelernter Automatisierungselektroniker:)

        Das habe ich mir längst gedacht 😉 Wer sonst hätte eine S7 zuhause 😊

        R 1 Reply Last reply Reply Quote 0
        • R
          ronny130286 @Armilar last edited by ronny130286

          @armilar

          Ich nutze eine Siemens Logo8 230v ist ähnlich und funktioniert über den S7 Adapter im Iobroker, eine S7 fand ich damals wie auch heute völlig drüber und auch teuer.

          Edit:
          Ich habe jetzt die Funktion ausgeschaltet, jetzt ist Ruhe mit dem triggern.
          Ich werden mir morgen mal das Thema mit der Fritzbox angucken, ich könnte mir vorstellen das es dort irgendwie ein unschönes zusammenspiel gibt.

          Aber so gefragt wenn ich die Buttons vom den Relays im Tasmot entkoppele, dann aber die Relay wieder im Script hart zusammenführen, ist das nicht eigentlich kontraproduktiv?
          Mir würde es jetzt nicht einfallen wann man das braucht?

          Armilar 1 Reply Last reply Reply Quote 0
          • Armilar
            Armilar Most Active Forum Testing @ronny130286 last edited by Armilar

            @ronny130286

            Aber so gefragt wenn ich die Buttons vom den Relays im Tasmot entkoppele, dann aber die Relay wieder im Script hart zusammenführen, ist das nicht eigentlich kontraproduktiv?

            Nein, denn du kannst deine Buttons losgelöst von den Relays nutzen. Die Relays aber dennoch mit Funktionen belegen.

            Beispiel. Du hast an einem Relay eine Heizung. Möchtest du an und ausschalten, jedoch über z.B. eine Blockly-Logik - nicht manuell über die Buttons.

            Auf dem anderen Relay hast du ebenfalls einen Verbraucher, den du schalten könntest, ohne dass du den Button benötigst.

            Die Button-Pages kannst du dann separat belegen...

            R 1 Reply Last reply Reply Quote 0
            • R
              ronny130286 @Armilar last edited by ronny130286

              @armilar

              Und was passiert mit dem dp unter 0_userdata. wenn ich das nicht entkoppelt? Wird der getriggert wenn das Relay schaltet?

              Armilar 1 Reply Last reply Reply Quote 0
              • Armilar
                Armilar Most Active Forum Testing @ronny130286 last edited by Armilar

                @ronny130286

                Die Datenpunkte visualisieren nur den Status des Relays, der sowieso über MQTT übertragen wird (somit ja, der wird getriggert, wenn das Relay schaltet!). Dennoch kannst du, wenn der Datenpunkt verändert wird via MQTT den Zustand des Relays schalten.

                Habe ein Panel in dem beide Varianten aktiv sind...

                R 1 Reply Last reply Reply Quote 0
                • R
                  ronny130286 @Armilar last edited by

                  @armilar

                  Ich überlege gerade, durch das schlecht wlan aktuellen wird wahrscheinlich beim mir das Signal verzögert im Kreis geschickt...

                  tasmota schickt per mqtt true an den iobroker, das kommt verzögert an, dann schreibt er es in den dp und tasmota schaltet wären dessen wieder auf false.

                  Da im dp jetzt ein true steht schickt das Script wieder über den http Befehl ein true an tasmota, damit schaltet tasmota wieder true false und so fängt es an sich aufzuschauckeln.

                  Manchmal ist das trigger auch fix vorbei und manchmal braucht es länger, was für ein Timing Problem sprechen würde.

                  Armilar 1 Reply Last reply Reply Quote 0
                  • Armilar
                    Armilar Most Active Forum Testing @ronny130286 last edited by

                    @ronny130286

                    Das kann natürlich sein. Dadurch dass durch deine Taster ja auch immer ein true/false initiiert wird, schaltet das noch häufiger.

                    R 1 Reply Last reply Reply Quote 0
                    • R
                      ronny130286 @Armilar last edited by ronny130286

                      @armilar
                      Puh, mal sehen vielleicht gibt es beim Tasmota ein deboucing für den MQTT Befehl den er in Richtung Iobroker schickt => mein normal ist mir der Zustand des Relay eh egal weil er nach 300ms eh immer false ist.

                      EDIT: da ich im Tasmota nicht schnell fündig geworden bin habe ich es versucht über das Script zu lösen, dabei bin ich über diese Funktion gestolpert:

                      async function SubscribeMRIcons () { 
                          try {
                              if (config.mrIcon1ScreensaverEntity.ScreensaverEntity != null) {
                                  on({id: config.mrIcon1ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function (obj) {
                                      if (obj.id.substring(0,4) == 'mqtt') {
                                          let Button = obj.id.split('.'); 
                                          if (getState(NSPanel_Path + 'Relay.' + Button[Button.length - 1].substring(5,6)).val != obj.state.val) {
                                              await setStateAsync(NSPanel_Path + 'Relay.' + Button[Button.length - 1].substring(5,6), obj.state.val == 'ON' ? true : false);
                                          }
                                      } else {
                                          HandleScreensaverStatusIcons();
                                      }
                                  });
                              }
                              if (config.mrIcon2ScreensaverEntity.ScreensaverEntity != null) {
                                  on({id: config.mrIcon2ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function (obj) {
                                      if (obj.id.substring(0,4) == 'mqtt') {
                                          let Button = obj.id.split('.'); 
                                          if (getState(NSPanel_Path + 'Relay.' + Button[Button.length - 1].substring(5,6)).val != obj.state.val) {
                                              await setStateAsync(NSPanel_Path + 'Relay.' + Button[Button.length - 1].substring(5,6), obj.state.val == 'ON' ? true : false);
                                          }
                                      } else {
                                          HandleScreensaverStatusIcons();
                                      }
                                  });
                              }
                          } catch (err) { 
                              console.warn('function SubscribeMRIcons: ' + err.message); 
                          }
                      }
                      

                      kommentiere ich SubscribeMRIcons(); aus, ist das Verhalten mit dem Falker auch weg und man kann die DP für Relay auch noch schreiben.

                      Armilar 1 Reply Last reply Reply Quote 0
                      • Armilar
                        Armilar Most Active Forum Testing @ronny130286 last edited by

                        @ronny130286

                        Ja, kannst du machen. Dadurch verlierst du allerdings die Möglichkeit die Relay's direkt über die Datenpunkte zu schalten (benötigst du aber ja eh nicht).

                        Mein Gedanke war, warum erzeugst du dir kein dezentrales Emulations-Steuerungsskript auf externe Datenpunkte für die Umwandlung Switches <--> Buttons?

                        Damit könntest du dir doch viele Anpassungen in diesem und anderen Skripten ersparen, oder?

                        R 1 Reply Last reply Reply Quote 0
                        • R
                          ronny130286 @Armilar last edited by ronny130286

                          @armilar

                          eigentlich ist es bei mir ja so, ich schaltet etwas mit dem MonoButton und gucke nach einem anderen Ausgang.
                          Bsp. Küche, ich triggere den Eingang an der SPS und gucke dann auf den Ausgang der mir den aktuellen Zustand gibt.

                          Ich sollte vielleicht einfach in der config den DP vom mqtt rausnehmen und dafür dein Ausgang der S7 eintragen, dann sollte es schon weg sein.

                          EDIT:

                          vielleicht wäre es auch denkbar die ScreensaverEntityValue anzuzeigen auch ohne einen ScreensaverEntity der einen Status anzeigt

                          Armilar 1 Reply Last reply Reply Quote 0
                          • T
                            Tom_W last edited by

                            Hallo zusammen,

                            nur eine kurze Frage: Ich habe im Screensaver ja 4 kleine Icons und davor ein großes.
                            Woher kommen die Werte von dem großen?
                            Dachte immer von alias Wetter.
                            Nur passt bei mit der Wert aus alias.0.Wetter.TEMP nicht mit der angezeigten Temperatur am Panel zusammen und nun frage ich mich, woher das Panel einen anderen Wert nimmt.
                            Es unterscheidet sich aktuell um 0,3 Grad.

                            Weiß das zufällig jemand?

                            Gruß

                            Tom

                            Armilar 1 Reply Last reply Reply Quote 0
                            • Armilar
                              Armilar Most Active Forum Testing @ronny130286 last edited by Armilar

                              @ronny130286 sagte in SONOFF NSPanel mit Lovelace UI:

                              vielleicht wäre es auch denkbar die ScreensaverEntityValue anzuzeigen auch ohne einen ScreensaverEntity der einen Status anzeigt

                              Da kann auch eine Waschmaschine oder ein Toaster rein 😉

                              EDIT:
                              Beispiel mit Fenstersensor und Temperatursensor:

                              mrIcon2ScreensaverEntity: { ScreensaverEntity: 'deconz.0.Sensors.5.open', 
                                                          ScreensaverEntityIconOn: 'heat-wave', 
                                                          ScreensaverEntityIconOff: null, 
                                                          ScreensaverEntityValue: 'deconz.0.Sensors.65.temperature',
                                                          ScreensaverEntityValueDecimalPlace : 1,
                                                          ScreensaverEntityValueUnit: '°', 
                                                          ScreensaverEntityOnColor: MSRed, 
                                                          ScreensaverEntityOffColor: MSGreen },
                              R 1 Reply Last reply Reply Quote 0
                              • Armilar
                                Armilar Most Active Forum Testing @Tom_W last edited by

                                @tom_w sagte in SONOFF NSPanel mit Lovelace UI:

                                alias.0.Wetter.TEMP

                                ist auch so. ICON und TEMP!

                                Welcher Datenpunkt ist denn unter TEMP eingetragen? ALIAS und Datenpunkt haben eigentlich immer den gleichen Wert.

                                T 1 Reply Last reply Reply Quote 0
                                • T
                                  Tom_W @Armilar last edited by

                                  @armilar Als Datenpunkt habe ich meinen Temperaturfühler eingetragen. Als Icon den Datenpunkt von accuweather.

                                  Datenpunkt und alias sind identisch, nur Anzeige am Panel zeigt nicht diesen Wert an der im Alias steht.

                                  Wollte nur wissen ob ich gedanklich schon richtig bin.
                                  Logge jetzt mal den Wert mit, eventuell springt mein Fühler auch einfach nur rum.

                                  Danke

                                  Armilar 1 Reply Last reply Reply Quote 0
                                  • Armilar
                                    Armilar Most Active Forum Testing @Tom_W last edited by

                                    @tom_w

                                    Kommt auf die Version an. Es gab Situationen, in denen das Updaten der 4 Icons und der Außentemperatur angehalten wurde, wenn nur einmal auf den Screensaver geklickt wurde.

                                    Sollte aber mit dem bExit-Hotfix ab der v3.9.0.2 behoben sein

                                    T 1 Reply Last reply Reply Quote 0
                                    • R
                                      ronny130286 @Armilar last edited by ronny130286

                                      @armilar

                                      ich habs mir zurecht gebaut: die Funktion CheckConfigParameters() muss man anpassen, da ansonsten eine Meldung in der Console erscheint => passiert auch sonst imnmer wenn man den wert auf null setzt

                                      if (existsObject(config.mrIcon1ScreensaverEntity.ScreensaverEntity) == false && config.mrIcon1ScreensaverEntity.ScreensaverEntity != null) {
                                                  console.warn('mrIcon1ScreensaverEntity data point in the config not available - please adjust');
                                              } 
                                              if (existsObject(config.mrIcon2ScreensaverEntity.ScreensaverEntity) == false && config.mrIcon2ScreensaverEntity.ScreensaverEntity != null) {
                                                  console.warn('mrIcon2ScreensaverEntity data point in the config not available - please adjust');
                                              } 
                                      

                                      und hier die HandleScreensaverStatusIcons() Funktion, damit kann man dann ScreensaverEntityValue anzeigen lassen ohne ScreensaverEntity einzutragen

                                      function HandleScreensaverStatusIcons() : void {
                                          try {
                                              let payloadString = '';
                                              let hwBtn1Col: any = config.mrIcon1ScreensaverEntity.ScreensaverEntityOffColor;
                                              if (config.mrIcon1ScreensaverEntity.ScreensaverEntity != null) {
                                                  if (typeof (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val) == 'string') {
                                                      let hwBtn1: string = getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val;
                                                      if (hwBtn1 == 'ON') {
                                                          hwBtn1Col = config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor;
                                                      }
                                                      if (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val) {
                                                          payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOn);
                                                      } else {
                                                          if (config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOff != null) {
                                                              payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOff);
                                                          } else {
                                                              payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOn);
                                                          }
                                                      } 
                                                      if (config.mrIcon1ScreensaverEntity.ScreensaverEntityValue != null) {
                                                          payloadString += (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntityValue).val).toFixed(config.mrIcon1ScreensaverEntity.ScreensaverEntityValueDecimalPlace);
                                                          payloadString += config.mrIcon1ScreensaverEntity.ScreensaverEntityValueUnit;                        
                                                      }
                                                      payloadString += '~' + rgb_dec565(hwBtn1Col) + '~';
                                                  } else if (typeof (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val) == 'boolean') {
                                                      let hwBtn1: boolean = getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val;
                                                      if (hwBtn1) {
                                                          hwBtn1Col = config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor;
                                                      }
                                                      if (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val) {
                                                          payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOn);
                                                      } else {
                                                          if (config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOff != null) {
                                                              payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOff);
                                                          } else {
                                                              payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOn);
                                                          }
                                                      } 
                                                      if (config.mrIcon1ScreensaverEntity.ScreensaverEntityValue != null) {
                                                          payloadString += (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntityValue).val).toFixed(config.mrIcon1ScreensaverEntity.ScreensaverEntityValueDecimalPlace);
                                                          payloadString += config.mrIcon1ScreensaverEntity.ScreensaverEntityValueUnit;                        
                                                      }
                                                      payloadString += '~' + rgb_dec565(hwBtn1Col) + '~';
                                                  }
                                              } else if (config.mrIcon1ScreensaverEntity.ScreensaverEntity == null && config.mrIcon1ScreensaverEntity.ScreensaverEntityValue != null){
                                                  
                                                  if(config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor != null){
                                                      hwBtn1Col = config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor;
                                                  }
                                                  if(config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOn != null){
                                                      payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIconOn);
                                                  }
                                                  
                                                  if (config.mrIcon1ScreensaverEntity.ScreensaverEntityValue != null) {
                                                      payloadString += (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntityValue).val).toFixed(config.mrIcon1ScreensaverEntity.ScreensaverEntityValueDecimalPlace);
                                                      payloadString += config.mrIcon1ScreensaverEntity.ScreensaverEntityValueUnit;                        
                                                  }
                                                  payloadString += '~' + rgb_dec565(hwBtn1Col) + '~';
                                              }
                                              else {
                                                  hwBtn1Col = Black;
                                                  payloadString += '~~';
                                              }
                                      
                                              let hwBtn2Col: any = config.mrIcon2ScreensaverEntity.ScreensaverEntityOffColor;
                                              if (config.mrIcon2ScreensaverEntity.ScreensaverEntity != null) {
                                                  if (typeof (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val) == 'string') {
                                                      let hwBtn2: string = getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val;
                                                      if (hwBtn2 == 'ON') {
                                                          hwBtn2Col = config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor;
                                                      }
                                                      if (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val) {
                                                          payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOn);
                                                      } else {
                                                          if (config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOff != null) {
                                                              payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOff);
                                                          } else {
                                                              payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOn);
                                                          }
                                                      } 
                                                      if (config.mrIcon2ScreensaverEntity.ScreensaverEntityValue != null) {
                                                          payloadString += (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntityValue).val).toFixed(config.mrIcon2ScreensaverEntity.ScreensaverEntityValueDecimalPlace);
                                                          payloadString += config.mrIcon2ScreensaverEntity.ScreensaverEntityValueUnit;                        
                                                      }
                                                      payloadString += '~' + rgb_dec565(hwBtn2Col) + '~';
                                                  } else if (typeof (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val) == 'boolean') {
                                                      let hwBtn2: boolean = getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val;
                                                      if (hwBtn2) {
                                                          hwBtn2Col = config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor;
                                                      }
                                                      if (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val) {
                                                          payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOn);
                                                      } else {
                                                          if (config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOff != null) {
                                                              payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOff);
                                                          } else {
                                                              payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOn);
                                                          }
                                                      } 
                                                      if (config.mrIcon2ScreensaverEntity.ScreensaverEntityValue != null) {
                                                          payloadString += (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntityValue).val).toFixed(config.mrIcon2ScreensaverEntity.ScreensaverEntityValueDecimalPlace);
                                                          payloadString += config.mrIcon2ScreensaverEntity.ScreensaverEntityValueUnit;                        
                                                      }
                                                      payloadString += '~' + rgb_dec565(hwBtn2Col) + '~';
                                                  }
                                              } else if (config.mrIcon2ScreensaverEntity.ScreensaverEntity == null && config.mrIcon2ScreensaverEntity.ScreensaverEntityValue != null){
                                                  
                                                  if(config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor != null){
                                                      hwBtn2Col = config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor;
                                                  }
                                      
                                                  if(config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOn != null){
                                                      payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIconOn);
                                                  }
                                                  
                                                  if (config.mrIcon2ScreensaverEntity.ScreensaverEntityValue != null) {
                                                      payloadString += (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntityValue).val).toFixed(config.mrIcon2ScreensaverEntity.ScreensaverEntityValueDecimalPlace);
                                                      payloadString += config.mrIcon2ScreensaverEntity.ScreensaverEntityValueUnit;                        
                                                  }
                                                  payloadString += '~' + rgb_dec565(hwBtn2Col) + '~';
                                              } else {
                                                  hwBtn2Col = Black;
                                                  payloadString += '~~';
                                              }
                                      
                                              let alternateScreensaverMFRIcon1Size = getState(NSPanel_Path + 'Config.MRIcons.alternateMRIconSize.1').val
                                              let alternateScreensaverMFRIcon2Size = getState(NSPanel_Path + 'Config.MRIcons.alternateMRIconSize.2').val
                                              //Alternate MRIcon Size
                                              if (alternateScreensaverMFRIcon1Size) {
                                                  payloadString += '1~';
                                              } else {
                                                  payloadString += '~';
                                              }
                                              if (alternateScreensaverMFRIcon2Size) {
                                                  payloadString += '1~';
                                              } else {
                                                  payloadString += '~';
                                              }
                                      
                                              SendToPanel(<Payload>{ payload: 'statusUpdate~' + payloadString });
                                      
                                          } catch (err) {
                                              console.log('HandleScreensaverStatusIcons: ' + err.message);
                                          }
                                      }
                                      
                                      1 Reply Last reply Reply Quote 1
                                      • Armilar
                                        Armilar Most Active Forum Testing last edited by

                                        @ronny130286

                                        Habe es mal in die 4.0.0 übernommen, da es eine sinnvolle Erweiterung für alle ist 😊

                                        Gargano 1 Reply Last reply Reply Quote 0
                                        • Gargano
                                          Gargano @Armilar last edited by

                                          @armilar Gibt es die 4.0.0 schon zum Testen ?

                                          Armilar 1 Reply Last reply Reply Quote 0
                                          • Armilar
                                            Armilar Most Active Forum Testing @Gargano last edited by

                                            @gargano

                                            Nee, die ist noch nicht öffentlich

                                            Gargano 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            862
                                            Online

                                            31.6k
                                            Users

                                            79.5k
                                            Topics

                                            1.3m
                                            Posts

                                            lovelace ui nspanel sonoff
                                            260
                                            7128
                                            4458301
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            Community
                                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                            The ioBroker Community 2014-2023
                                            logo