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. Visualisierung
  4. Handhabung von Socket für VIS-Alternative

NEWS

  • Neuer ioBroker-Blog online: Monatsrückblick März/April 2026
    BluefoxB
    Bluefox
    7
    1
    277

  • Verwendung von KI bitte immer deutlich kennzeichnen
    HomoranH
    Homoran
    9
    1
    254

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

Handhabung von Socket für VIS-Alternative

Geplant Angeheftet Gesperrt Verschoben Visualisierung
socket iomobile uivisown project
5 Beiträge 2 Kommentatoren 536 Aufrufe 2 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.
  • KLVNK Offline
    KLVNK Offline
    KLVN
    schrieb am zuletzt editiert von
    #1

    Moin,
    ich bin gerade dabei meine eigene VIS-Alternative zu schreiben, die genau auf meine Bedürfnisse zugeschnitten ist. Bin jetzt schon so weit, dass die Website die aktuellen Zustände über Socket.io empfängt, visualisiert und auch vom User geänderte Zustände wieder an ioBroker überträgt. Das klappt meistens auch ganz gut, doch manchmal komme ich in eine Art Schleife, in der ein empfangener Wert gesetzt wird und zeitgleich ein geänderter Wert wieder an den Server übertragen wird. Weil das setzen eines Wertes wieder die Senden-Funktion triggert, wird dieser Wert wieder gesendet und zeitgleich wieder der vorherige Wert vom Server empfangen und gesetzt. Das führt dazu, dass z.B. der Slider im Screenshot sehr schnell zwischen diesen beiden Werten hin und her springt.

    Bisschen anschaulicher erklärt:
    1 . Server-Wert = 80 und wird empfangen
    1 . Zeitgleich wird Slider auf Lokal-Wert = 30 gesetzt und an den Server gesendet
    2 . jetzt wird der empfangene Wert (80) auf den Slider übertragen
    2 . Änderung des Sliders --> Sende Wert 80 an Server
    3 . Zeitgleich wird der vorherige Wert (30) empfangen und wieder auf Slider übertragen
    4 . Änderung führt wieder zum Senden an Server
    5 . und das geht dann ewig

    Beide Seiten kämpfen richtig darum, ihren eigenen Wert durchzudrücken und dabei tauschen sie dann immer nur die jeweiligen Werte zyklisch aus.

    Bis jetzt das Grundgerüst. Wenn die Verbindung erstmal vernünftig funktioniert, ist der Rest einfach:
    Bild Text

    Aktueller Code.
    Wenn servConn() ein Update bekommt, werden die States emitted. Der nächste Abschnitt ist der Event Listener, der auf dieses Update hört, alle HTML Elemente mit der Klasse .iobroker-state sucht und je nach Typ (bis jetzt Toggle oder Slider) dann die entsprechenden Werte aus dem Array States setzt. Die HTML-Elemente haben noch ein Tag data-id="Shelly.blabla" über die ich dann die richtigen Werte aus dem Array zuordne.
    Der letzte Abschnitt achtet auf alle Elemente mit der Klasse .iobroker-state und bei einer Änderung wird wieder nach Typ unterschieden und dann mit der entsprechenden ID der neue Wert an den Server gesendet.

    var states = [];
    servConn.init({
      
      onUpdate: function (id, state) {
          setTimeout(function () {
            states[id] = state;
            app.emit('smarthomeStates', states);
          }, 0);
        },
      [...]
    });
    
    
    // RECEIVE states and update
    app.on('smarthomeStates', function (states) {
      elements = document.getElementsByClassName("iobroker-state")
    
      for(var i = 0; i < elements.length; i++) {
        if ((elements[i].classList).contains("toggle")) {
          app.toggle.get(elements[i]).checked = states[elements[i].dataset.id]["val"];
    
        } else if ((elements[i].classList).contains("range-slider")) {
          app.range.get(elements[i]).setValue(states[elements[i].dataset.id]["val"]);
        }
      }
    });
    
    
    // TRANSMIT states on change
    // erst wenn Änderung abgeschlossen wurde, also nicht kontinuierlich senden, während man den Slider noch verschiebt
    $('.iobroker-state').on('touchend mouseleave', function (e) {
      if ((e.srcElement.classList).contains("toggle")) {
        var toggle = app.toggle.get(e.target);
        servConn.setState(e.srcElement.dataset.id, toggle.checked)
      
      } else if ((e.srcElement.classList).contains("range-slider")) {
        var range = app.range.get(e.target);
        servConn.setState(e.srcElement.dataset.id, range.value)
      }
    
    });
    

    Wie wird das bei VIS gehandhabt bzw. wie kann ich verhindern, dass Client und Server sich darum prügeln, immer den aktuellen Wert an den jeweils anderen zu senden?

    ScroungerS 1 Antwort Letzte Antwort
    0
    • KLVNK KLVN

      Moin,
      ich bin gerade dabei meine eigene VIS-Alternative zu schreiben, die genau auf meine Bedürfnisse zugeschnitten ist. Bin jetzt schon so weit, dass die Website die aktuellen Zustände über Socket.io empfängt, visualisiert und auch vom User geänderte Zustände wieder an ioBroker überträgt. Das klappt meistens auch ganz gut, doch manchmal komme ich in eine Art Schleife, in der ein empfangener Wert gesetzt wird und zeitgleich ein geänderter Wert wieder an den Server übertragen wird. Weil das setzen eines Wertes wieder die Senden-Funktion triggert, wird dieser Wert wieder gesendet und zeitgleich wieder der vorherige Wert vom Server empfangen und gesetzt. Das führt dazu, dass z.B. der Slider im Screenshot sehr schnell zwischen diesen beiden Werten hin und her springt.

      Bisschen anschaulicher erklärt:
      1 . Server-Wert = 80 und wird empfangen
      1 . Zeitgleich wird Slider auf Lokal-Wert = 30 gesetzt und an den Server gesendet
      2 . jetzt wird der empfangene Wert (80) auf den Slider übertragen
      2 . Änderung des Sliders --> Sende Wert 80 an Server
      3 . Zeitgleich wird der vorherige Wert (30) empfangen und wieder auf Slider übertragen
      4 . Änderung führt wieder zum Senden an Server
      5 . und das geht dann ewig

      Beide Seiten kämpfen richtig darum, ihren eigenen Wert durchzudrücken und dabei tauschen sie dann immer nur die jeweiligen Werte zyklisch aus.

      Bis jetzt das Grundgerüst. Wenn die Verbindung erstmal vernünftig funktioniert, ist der Rest einfach:
      Bild Text

      Aktueller Code.
      Wenn servConn() ein Update bekommt, werden die States emitted. Der nächste Abschnitt ist der Event Listener, der auf dieses Update hört, alle HTML Elemente mit der Klasse .iobroker-state sucht und je nach Typ (bis jetzt Toggle oder Slider) dann die entsprechenden Werte aus dem Array States setzt. Die HTML-Elemente haben noch ein Tag data-id="Shelly.blabla" über die ich dann die richtigen Werte aus dem Array zuordne.
      Der letzte Abschnitt achtet auf alle Elemente mit der Klasse .iobroker-state und bei einer Änderung wird wieder nach Typ unterschieden und dann mit der entsprechenden ID der neue Wert an den Server gesendet.

      var states = [];
      servConn.init({
        
        onUpdate: function (id, state) {
            setTimeout(function () {
              states[id] = state;
              app.emit('smarthomeStates', states);
            }, 0);
          },
        [...]
      });
      
      
      // RECEIVE states and update
      app.on('smarthomeStates', function (states) {
        elements = document.getElementsByClassName("iobroker-state")
      
        for(var i = 0; i < elements.length; i++) {
          if ((elements[i].classList).contains("toggle")) {
            app.toggle.get(elements[i]).checked = states[elements[i].dataset.id]["val"];
      
          } else if ((elements[i].classList).contains("range-slider")) {
            app.range.get(elements[i]).setValue(states[elements[i].dataset.id]["val"]);
          }
        }
      });
      
      
      // TRANSMIT states on change
      // erst wenn Änderung abgeschlossen wurde, also nicht kontinuierlich senden, während man den Slider noch verschiebt
      $('.iobroker-state').on('touchend mouseleave', function (e) {
        if ((e.srcElement.classList).contains("toggle")) {
          var toggle = app.toggle.get(e.target);
          servConn.setState(e.srcElement.dataset.id, toggle.checked)
        
        } else if ((e.srcElement.classList).contains("range-slider")) {
          var range = app.range.get(e.target);
          servConn.setState(e.srcElement.dataset.id, range.value)
        }
      
      });
      

      Wie wird das bei VIS gehandhabt bzw. wie kann ich verhindern, dass Client und Server sich darum prügeln, immer den aktuellen Wert an den jeweils anderen zu senden?

      ScroungerS Offline
      ScroungerS Offline
      Scrounger
      Developer
      schrieb am zuletzt editiert von Scrounger
      #2

      @KLVN
      Ohne jetzt deinem Beispiel wirklich folgen zu können, würde ich es über die state property from versuchen. Diese gibt an von wem der Wert geändert wurde. D.h. wenn eine Änderung durch vis erfolgte, darfst du mit deinem Code dann nicht darauf reagieren. Kommt die Änderung z.B. vom Shelly Adapter, dann in VIS darauf reagieren.

      KLVNK 1 Antwort Letzte Antwort
      0
      • ScroungerS Scrounger

        @KLVN
        Ohne jetzt deinem Beispiel wirklich folgen zu können, würde ich es über die state property from versuchen. Diese gibt an von wem der Wert geändert wurde. D.h. wenn eine Änderung durch vis erfolgte, darfst du mit deinem Code dann nicht darauf reagieren. Kommt die Änderung z.B. vom Shelly Adapter, dann in VIS darauf reagieren.

        KLVNK Offline
        KLVNK Offline
        KLVN
        schrieb am zuletzt editiert von
        #3

        @Scrounger
        Danke, das behebt schon mal den unendlichen Loop. Wenn ich den Slider gedrückt halte und verschiebe, zappelt er danach noch etwas, aber pendelt sich dann auch wieder ein - das war vorher nicht der Fall. Ich bin deinem Ansatz gefolgt und ignoriere jetzt States, die von system.adapter.web.0 oder system.adapter.socketio.0 kommen. Damit bleiben nur noch die Adapter der eigentlichen Geräte, wie z.B. system.adapter.shelly.0 übrig. Zusätzlich pausiere ich die Funktion, die für das Aktualisieren sorgt, wenn der Benutzer gerade ein Element ändert.
        Ich werde die Sache noch etwas verfeinern.

        ScroungerS 1 Antwort Letzte Antwort
        0
        • KLVNK KLVN

          @Scrounger
          Danke, das behebt schon mal den unendlichen Loop. Wenn ich den Slider gedrückt halte und verschiebe, zappelt er danach noch etwas, aber pendelt sich dann auch wieder ein - das war vorher nicht der Fall. Ich bin deinem Ansatz gefolgt und ignoriere jetzt States, die von system.adapter.web.0 oder system.adapter.socketio.0 kommen. Damit bleiben nur noch die Adapter der eigentlichen Geräte, wie z.B. system.adapter.shelly.0 übrig. Zusätzlich pausiere ich die Funktion, die für das Aktualisieren sorgt, wenn der Benutzer gerade ein Element ändert.
          Ich werde die Sache noch etwas verfeinern.

          ScroungerS Offline
          ScroungerS Offline
          Scrounger
          Developer
          schrieb am zuletzt editiert von
          #4

          @KLVN
          Das gezappel kenn ich von der Entwicklung der Material Design Widgets.
          Du musst den Slider so auslegen, dass er nur bei touchend / mouse up / key up einen Wert schreibt bzw. an iob schickt.

          Bzgl. handling der state change events würde ich dir empfehlen, anzuschauen wie das der VIS Adapter macht: https://github.com/ioBroker/ioBroker.vis/blob/master/www/js/vis.js

          1 Antwort Letzte Antwort
          1
          • KLVNK Offline
            KLVNK Offline
            KLVN
            schrieb am zuletzt editiert von
            #5

            Moin,
            es ist etwas Zeit ins Land gegangen, aber nun habe ich auch wieder mehr Zeit für die Entwicklung. Die Funktion achtet jetzt auf touchend mouseup keydown und solange man den Schalter nicht gedrückt hält und hin und her schiebt, funktioniert das alles auch. Zusätzlich unterbreche ich den Event listener, der für das aktualisieren der Zustände verantwortlich ist, sobald man die Schalter benutzt hat. Aktueller Ablauf ist jetzt:

            • Zustände aktualisieren, wenn der Socket onUpdate() auslöst
            • Wenn z.B. ein Schalter geändert wurde (touchend ...), dann stoppe Aktualisierung, sende neuen Zustand, starte Aktualisierung

            Dieses Flackern tritt immer noch auf, doch ich denke, dass es an dem Framework liegt, das ich für die Darstellung benutze. Das hat ein paar Kinderkrankheiten und sendet unter anderem ein Event, bevor die Animation durchgelaufen ist, was schon für ordentlich Verwirrung gesorgt hat. Ich muss wohl noch ein paar Timeouts/waits einfügen, damit eine State-Änderung erst als abgeschlossen gilt, wenn die betroffenen Elemente geändert wurden und auch mit den Animationen fertig sind.

            Den Code von VIS habe ich mir angesehen und konnte auch ein paar Tricks finden. Auch deinen (@Scrounger ) Code für die Widgets habe ich gelesen, konnte jetzt aber nicht die Stelle finden, an der ein neuer Zustand gesendet wird.

            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

            316

            Online

            32.8k

            Benutzer

            82.8k

            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