Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Entwicklung
    4. [neuer Adapter] snapcast

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    [neuer Adapter] snapcast

    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      jampr last edited by jampr

      Hi zusammen,

      ich baue für mich gerade einen neuen Adapter für snapcast.

      Zuerst hatte ich hier angefangen, das mit dem Script-Adapter zu steuern. Dann per iFrame direkt über das in snapcast mitgelierferte Snapweb.

      Jetzt wollte ich das mal auf vernünftige Beine stellen.

      Bisher kann der Adapter Host und Port im AdminUI erfassen und danach eine Websocket-Verbindung über json_rpc_api zum snapserver aufbauen.

      Nachrichten senden, results zurückbekommen und push notifications empfangen klappt auch wunderbar. (im Moment noch ins Log geschrieben)

      Jetzt zu meinen Fragen:

      1. Die Clients bekommt man nur raus, indem man den gesamten Server-Status abfragt.
        ist es sinnvoll bzw notwendig, die gesamte Struktur als States zu hinterlegen? Das ist ja ganz schön fusselig, jede Eigenschaft als state anzulegen, zu aktualisieren und zu löschen (wenn ein Client aus gemacht wird).
        Oder reicht es einen State anzulegen, in dem dieses Result drin steht?

      2. Wie kann ich im VIS das Ganze darstellen?
        Letztendlich wollte ich eine Liste ähnlich zum snapweb anzeigen lassen. Ich bin leider schon bei den ersten Postings daran gescheitert, das Json-Result im vis in nem html-area darzustellen. Oder besser als widget?

      Mein Wunsch wäre folgendes:

      • Clients steuern (Lautstärke, Gruppen, Streams)
      • eine Art Filebrowser, um ein paar Verzeichnisse mit alten mp3 durchstöbern und die jeweilige Playlist an einen ausgewählten Stream zu schicken. (vielleicht mit Cover-Bildern, um es Kinder-kompatibel zu machen)

      was mich zu meiner Frage 3 bringt:
      3) sollte so ein File-browsing mit in so einen Adapter integriert oder separat sein. Bei mir ist das eh alles auf dem selben Host.

      und zum Schluss noch:
      4) besteht überhaupt Bedarf, dass andere sowas nutzen wollen?

      Liebe Grüße
      & ein Frohes Neues noch

      1 Reply Last reply Reply Quote 0
      • J
        jampr last edited by

        Ich schäme mich zwar etwas, aber hier der Adapter:
        https://github.com/jampr21/ioBroker.snapcast

        1 Reply Last reply Reply Quote 1
        • J
          jampr last edited by

          aus dem Snapweb werde ich die Struktur übernehmen.

          J 1 Reply Last reply Reply Quote 0
          • J
            jampr @jampr last edited by jampr

            Typescript-Adapter-Basis ist eingecheckt. Vielen Dank nochmal an AlCalzone für den Chat.

            Allerdings brauche ich immer noch einen Tipp, wie ich die Werte am Sinnvollsten speichere, damit die im VIS als Widget angezeigt werden können.

            J 1 Reply Last reply Reply Quote 0
            • J
              jampr @jampr last edited by

              beim Punkt 2. bin ich etwas weiter gekommen. Ich habe die Datei-Liste erstmal in einem basic-html gebaut und will das dann in ein eigenes Widget im Adapter packen.

              Allerdings habe ich da noch einige Probleme. Zum Einen wird der Zurück-Knopf machmal zwei Mal dargestellt.

              <div id="prev"></div> <br>
              <div id="pathList"></div> 
              
              <script>
              
              function updateStat (btn){
                  var objID1 = "snapcast.0.currentPath";
                  this.servConn._socket.emit('setState', objID1, btn.value );
              }
              
              vis.conn._socket.emit('getState', "snapcast.0.currentPath", function (err, state) {
                      var pathAndFile =state.val;
                      var prevPath = pathAndFile.substring(0, pathAndFile.lastIndexOf('/'));
                      var table = "<table>";        
                      table += "<tr> ";
                      table += '<td><button style="width: 100%; height: 100%;" value=\"'+ prevPath +'\" onclick=updateStat(this)>&nbsp; <<----&nbsp;&nbsp;'+prevPath+' &nbsp;</button></td>';
                      table += '<td>'+ '&nbsp;' +'</td>'; 
                      table += "</tr> ";  
                      table += "</table>";
                      document.getElementById("prev").innerHTML += table;
                      document.getElementById("prev").innerHTML += pathAndFile.substring(pathAndFile.lastIndexOf('/')+1, pathAndFile.length);
              });
              
              vis.conn._socket.emit('getState', "snapcast.0.currentPathList", function (err, state) {
                  
                  var data = JSON.parse(state.val);
                  var table = "<table>";
                  
                  for (var i = 0; i < data.length; i++) {
                      var lbl = "";
               
                      if (data[i][Object.keys(data[i])[2]] =="mp3" || data[i][Object.keys(data[i])[2]] == "directory"){
                          table += '<tr>';
                     	    if (data[i][Object.keys(data[i])[2]] == "directory"){
                  	        lbl = "---->>&nbsp;&nbsp;";
                  	    }
                  	    var pathAndFile = data[i][Object.keys(data[i])[0]] +"/" +  data[i][Object.keys(data[i])[1]];
                          table += '<td><button style="width: 100%; height: 100%; text-align: left;" value=\"'+ pathAndFile +'\" onclick=updateStat(this)>'+ lbl + data[i][Object.keys(data[i])[1]] +'</button></td>';
                          table += '</tr>';
                      }
                  }
                  table += " </table>";
                          
                  document.getElementById("pathList").innerHTML += table;
              });
               
               
              </script>
              
              <!--
              <div  style="display:none">{snapcast.0.currentPathList}</div>
              <div  style="display:none">{snapcast.0.currentPath}</div>
              -->
              

              Und zum Anderen fehlt mir etwas das Verständnis des Widget-Templates.

              • woher kommen die Werte für <%= this.data.attr('wid') %> und <%== this.data.attr('class') %>, also das data?
              • wie funktioniert das Aktualisieren bei einer Änderung am State
              Stikkx 1 Reply Last reply Reply Quote 1
              • Stikkx
                Stikkx @jampr last edited by

                Hi @jampr,

                ich befasse mich gerade etwas mit Snapcast und baue mir gerade eine neue iobroker instance auf, da wir umgezogen sind.
                Hast du inzwischen deinen Adapter weiterentwickelt ? Falls nicht, ich würde dir gern dabei helfen.

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

                Support us

                ioBroker
                Community Adapters
                Donate

                540
                Online

                31.7k
                Users

                79.8k
                Topics

                1.3m
                Posts

                fragen neuer adapter widget
                2
                6
                643
                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