Skip to content
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. [Vorlage] Denon HEOS Script

NEWS

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

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

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

[Vorlage] Denon HEOS Script

Geplant Angeheftet Gesperrt Verschoben JavaScript
javascripttemplate
357 Beiträge 48 Kommentatoren 75.9k Aufrufe 44 Watching
  • Ä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.
  • S sveni_lee

    ich habe dein super Script mal angefangen auf meine Bedürfnisse anzupassen.
    Mein Problem war das die Sortierung nicht gepasst hat und das ich auch nicht einen Ordner aufwärts navigieren konnte.
    Beide Punkte konnte ich umsetzen. Als nächstes werde ich versuchen die Tietel auf der untersten ebene noch anzupassen.
    Bei mir werden derzeit nur die Titel und nicht die interpreten angezeigt und auch nicht in der Reihenfolge wir sie auf der CD sind...

    on({id: 'heos.0.sources.browse_result', change: 'any'}, function (obj) {
    
        let data = JSON.parse(obj.state.val); //data = JSON.parse(json).data;
    
        let html = ""
    
        if(data){
    
    //        html += "<div style=\"background-color:#3b3b3b;color:#fff\"><h1><img src=\"" + data.image_url + "\" height=\"30px\">" + data.name + "</h1>"
            var str = data.parameter.cid;
            log(data.parameter.cid)
            if(str.includes("fol")) {
                let pos = str.lastIndexOf('/')
                str = str.substr(0, pos);
                let upwarts = "browse/browse?sid=" + data.name + "&cid=" + str
                html += "<table>"
                html += "<tr>";
                html += "<td>";
                
                html += "<button class=\"ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only\" onClick=\"servConn.setState('heos.0.command','" + upwarts +"')\"><span class=\"ui-button-text\">" + "zurück" + "</span></button>";
                html += "</td>";
                html += "</tr>";
            }
    
            let sorted = (data.payload).sort(compareValues('name'));
    
            for (let i = 0; i < sorted.length; i++) {
    
                let payload = sorted[i];
                
                if (payload.name != "Navigate to top") {
    
                    html += "<tr>";
    
                    html += "<td><img src=\"" + payload.image_url + "\" height=\"30px\"></td>";
    
                    html += "<td>" + payload.name + "</td>";
    
                    html += "<td>";
    
                    for (let key in payload.commands) {
    
                        let command = payload.commands[key];
    
                        html += "<button class=\"ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only\" onClick=\"servConn.setState('heos.0.command','" + command +"')\"><span class=\"ui-button-text\">" + key + "</span></button>";
    
                    }
    
                    html += "</td>";
    
                    html += "</tr>";
    
                }
    
            }
    
            html += "</table></div>";
    
        }
    
        setState("0_userdata.0.scriptData.HeosBrowseTable", html);
    
    });
    
    function compareValues(key, order = 'asc') {
      return function innerSort(a, b) {
        if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
          // property doesn't exist on either object
          return 0;
        }
    
        const varA = (typeof a[key] === 'string')
          ? a[key].toUpperCase() : a[key];
        const varB = (typeof b[key] === 'string')
          ? b[key].toUpperCase() : b[key];
    
        let comparison = 0;
        if (varA > varB) {
          comparison = 1;
        } else if (varA < varB) {
          comparison = -1;
        }
        return (
          (order === 'desc') ? (comparison * -1) : comparison
        );
      };
    }
    
    

    2.JPG

    H Offline
    H Offline
    hotze78
    schrieb am zuletzt editiert von hotze78
    #197

    @sveni_lee sagte in [Vorlage] Denon HEOS Script:

    Bei deiner Wariante bekomme ich im Log eine Fehlermeldungen. Beginnt mit
    (950) Error in callback: TypeError: Cannot read property 'includes' of undefined
    withstu sein Script funktioniert. Ein Zurück währe sicher vorteilhaft.
    Anstatt ein Button währe mir lieber wenn der Text auswählbar währe. Oder ein Flat Box um den Text. Bei einem Ordner ein Ordner Symbol dort wo ja auch ein Cover geht.

    S 1 Antwort Letzte Antwort
    0
    • H hotze78

      @sveni_lee sagte in [Vorlage] Denon HEOS Script:

      Bei deiner Wariante bekomme ich im Log eine Fehlermeldungen. Beginnt mit
      (950) Error in callback: TypeError: Cannot read property 'includes' of undefined
      withstu sein Script funktioniert. Ein Zurück währe sicher vorteilhaft.
      Anstatt ein Button währe mir lieber wenn der Text auswählbar währe. Oder ein Flat Box um den Text. Bei einem Ordner ein Ordner Symbol dort wo ja auch ein Cover geht.

      S Offline
      S Offline
      sveni_lee
      schrieb am zuletzt editiert von
      #198

      @hotze78

      hmm.... bei mir läuft es ohne Probleme.
      Du kannst eventuell mal die Zeile 12 ändern.

      let str = data.parameter.cid;
      

      im Grunde wird damit die Abfrage eingeleitet ob es noch einen übergeordneten Otdner gibt.

      W 1 Antwort Letzte Antwort
      0
      • S sveni_lee

        @hotze78

        hmm.... bei mir läuft es ohne Probleme.
        Du kannst eventuell mal die Zeile 12 ändern.

        let str = data.parameter.cid;
        

        im Grunde wird damit die Abfrage eingeleitet ob es noch einen übergeordneten Otdner gibt.

        W Offline
        W Offline
        withstu
        schrieb am zuletzt editiert von withstu
        #199

        @sveni_lee Die Sortierung und der Zurück Button ist jetzt auch in der neuen Version 1.3.1 zu finden. Und die Queue ist jetzt pro Player auch als JSON verfügbar.

        on({id: 'heos.0.sources.browse_result', change: 'any'}, function (obj) {
          let data = JSON.parse(obj.state.val);
          let html = ""
          if(data){
              html += "<div style=\"background-color:#3b3b3b;color:#fff\"><h1>"
              if(data.image_url.length > 0){
                html += "<img src=\"" + data.image_url + "\" height=\"30px\">";
              }
              html += (data.name == "sources" ? "Overview" : data.name) + "</h1>"
              html += "<table>"
              for (let i = 0; i < data.payload.length; i++) {
                  let payload = data.payload[i];
                  html += "<tr";
                  if(payload.type == "control"){
                    html += " style=\"color:#ffa500\"";
                  }
                  html += ">";
                  html += "<td>";
                  if(payload.image_url.length > 0){
                    html += "<img src=\"" + payload.image_url + "\" height=\"30px\">";
                  }
                  html += "</td>";
                  html += "<td>"
                  if(payload.type == "control"){
                    switch(payload.name){
                      case "load_next":
                        html += "Next page";
                        break;
                      case "load_prev":
                        html += "Previous page";
                        break;
                      case "play_all":
                        html += "Play all";
                        break;
                      case "back":
                        html += "Back";
                        break;
                      case "sources":
                        html += "Overview";
                        break;
                    }
                  } else {
                    html += payload.name;
                  }
                  html +="</td>";
                  html += "<td>";
                  for (let key in payload.commands) {
                      let command = payload.commands[key];
                      html += "<button class=\"ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only\" onClick=\"servConn.setState('heos.0.command','" + command +"')\"><span class=\"ui-button-text\">" 
                      switch(key){
                        case "play":
                          html += "Play";
                          break;
                        case "browse":
                          html += "Browse";
                          break;
                      }
                      html += "</span></button>";
                  }
                  html += "</td>";
                  html += "</tr>";
              }
              html += "</table></div>";
          }
          setState("0_userdata.0.scriptData.HeosBrowseTable", html);
        });
        
        S 1 Antwort Letzte Antwort
        0
        • W withstu

          @sveni_lee Die Sortierung und der Zurück Button ist jetzt auch in der neuen Version 1.3.1 zu finden. Und die Queue ist jetzt pro Player auch als JSON verfügbar.

          on({id: 'heos.0.sources.browse_result', change: 'any'}, function (obj) {
            let data = JSON.parse(obj.state.val);
            let html = ""
            if(data){
                html += "<div style=\"background-color:#3b3b3b;color:#fff\"><h1>"
                if(data.image_url.length > 0){
                  html += "<img src=\"" + data.image_url + "\" height=\"30px\">";
                }
                html += (data.name == "sources" ? "Overview" : data.name) + "</h1>"
                html += "<table>"
                for (let i = 0; i < data.payload.length; i++) {
                    let payload = data.payload[i];
                    html += "<tr";
                    if(payload.type == "control"){
                      html += " style=\"color:#ffa500\"";
                    }
                    html += ">";
                    html += "<td>";
                    if(payload.image_url.length > 0){
                      html += "<img src=\"" + payload.image_url + "\" height=\"30px\">";
                    }
                    html += "</td>";
                    html += "<td>"
                    if(payload.type == "control"){
                      switch(payload.name){
                        case "load_next":
                          html += "Next page";
                          break;
                        case "load_prev":
                          html += "Previous page";
                          break;
                        case "play_all":
                          html += "Play all";
                          break;
                        case "back":
                          html += "Back";
                          break;
                        case "sources":
                          html += "Overview";
                          break;
                      }
                    } else {
                      html += payload.name;
                    }
                    html +="</td>";
                    html += "<td>";
                    for (let key in payload.commands) {
                        let command = payload.commands[key];
                        html += "<button class=\"ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only\" onClick=\"servConn.setState('heos.0.command','" + command +"')\"><span class=\"ui-button-text\">" 
                        switch(key){
                          case "play":
                            html += "Play";
                            break;
                          case "browse":
                            html += "Browse";
                            break;
                        }
                        html += "</span></button>";
                    }
                    html += "</td>";
                    html += "</tr>";
                }
                html += "</table></div>";
            }
            setState("0_userdata.0.scriptData.HeosBrowseTable", html);
          });
          
          S Offline
          S Offline
          sveni_lee
          schrieb am zuletzt editiert von
          #200

          @withstu sagte in [Vorlage] Denon HEOS Script:
          Hi withstu

          Du kannst die Abfrage:

          if(data.image_url.length > 0)
          

          auch wie folgt abändern:

          if(data.image_url.length)
          

          dann gibt das ein "true" zurück wenn vorhanden... ansonsten gibt es einen fehler wenn data.image_url nicht vorhanden ist.

          1 Antwort Letzte Antwort
          0
          • S sveni_lee

            also ich muß schon sagen, ich bin begeistert. Das sieht schon richtig gut aus.

            zwei kurze Frage hätte ich noch 🙂
            könnte man den Text linksbündig und die button rechtsbündig machen?
            un gibt es eine möglichleit die Auswahlliste zu sortieren. Ich weiß nicht warum HEOS die
            so durcheinnder würfelt.

            Danke!1.JPG

            W Offline
            W Offline
            withstu
            schrieb am zuletzt editiert von withstu
            #201

            @sveni_lee Danke. Habe es geändert in Version 1.3.3. Das Script habe ich übrigens so geschrieben, dass jeder selber sein Design hinterlegen kann. Wenn du den Text linksbündig und die Buttons rechtsbündig haben willst, musst du "text-align" bei den td Elementen hinzufügen:
            Rechtsbündig:

            html += "<td style\"text-align:right\">";
            

            Linksbündig:

            html += "<td style\"text-align:left\">";
            

            Bei mir sieht es aktuell so aus:

            on({id: 'heos.0.sources.browse_result', change: 'any'}, function (obj) {
              let data = JSON.parse(obj.state.val);
              let html = `<style>
              .heos-browse {
                  background-color: #333333;
                  color: #eaeaea;
              }
              .heos-browse table {
                  width: 100%;
                  border-collapse: collapse;
              }
              .heos-browse table, th, td {
                  border: 1px solid #929292;
                  border-width:1px 0;
              }
              .heos-browse th {
                  font-size: 2em;
                  border: 1px solid #c50000;
                  border-width: 0 0 1px 0;
                  text-align: center;
              }
              .heos-browse th,td {
                  padding: 15px;
              }
              .heos-browse-btn {
                  color: #fff;
                  background-color: Transparent;
                  background-repeat:no-repeat;
                  border: none;
                  cursor:pointer;
                  overflow: hidden;
                  outline:none;
                  margin: 0;
                  padding: 0;
                  font-size: 30px !important;
                  line-height: 30px;
                  width: 60px;
                  height: 60px;
              }
              .heos-browse-btn-multi {
                  border-right: 1px solid #929292;
              }
              .heos-browse-row-media {
            
              }
              .heos-browse-row-control {
                  color: #d60000;
              }
              .heos-browse-image {
                  white-space: nowrap;
                  padding: 0;
                  text-align: right;
                  font-size: 0;
              }
              .heos-browse-image img {
                  height: 60px;
              }
              .heos-browse-name {
                  width: 100%;
                  text-align: left;
              }
              .heos-browse-control {
                  padding: 0;
                  margin: 0;
                  white-space: nowrap;
                  font-size: 0;
                  text-align: right;
              }
              </style>`;
              if(data){
                  html += "<div class=\"heos-browse\">"
                  html += "<table>"
                  html += "<tr><th>";
                  if(data.image_url.length){
                      html += "<img src=\"" + data.image_url + "\" height=\"30px\">";
                  }
                  html += "</th><th>" + (data.name == "sources" ? "Overview" : data.name) + "</th><th></th></tr>";
                  for (let i = 0; i < data.payload.length; i++) {
                      let payload = data.payload[i];
                      html += "<tr class=\"";
                      if(payload.type == "control"){
                        html += "heos-browse-row-control";
                      } else {
                          html += "heos-browse-row-media"
                      }
                      html += "\">";
                      html += "<td class=\"heos-browse-image\"";
                      if("browse" in payload.commands){
                          html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands["browse"] +"')\"";
                      } else if(Object.keys(payload.commands).length == 1){
                          html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands[Object.keys(payload.commands)[0]] +"')\"";
                      }
                      html += ">"
                      if(payload.image_url.length){
                        html += "<img src=\"" + payload.image_url + "\">";
                      }
                      html += "</td>";
                      html += "<td class=\"heos-browse-name\"";
                      if("browse" in payload.commands){
                          html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands["browse"] +"')\"";
                      } else if(Object.keys(payload.commands).length == 1){
                          html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands[Object.keys(payload.commands)[0]] +"')\"";
                      }
                      html += ">"
                      if(payload.type == "control"){
                        switch(payload.name){
                          case "load_next":
                            html += "Next page";
                            break;
                          case "load_prev":
                            html += "Previous page";
                            break;
                          case "play_all":
                            html += "Play all";
                            break;
                          case "back":
                            html += "Back";
                            break;
                          case "sources":
                            html += "Overview";
                            break;
                        }
                      } else {
                        html += payload.name;
                      }
                      html +="</td>";
                      html += "<td class=\"heos-browse-control\">";
                      for (let key in payload.commands) {
                        let command = payload.commands[key];
                        html += "<button class=\"heos-browse-btn"
                        if(Object.keys(payload.commands).length > 1){
                            html += " heos-browse-btn-multi"
                        }
                        html += "\" onClick=\"servConn.setState('heos.0.command','" + command +"')\">" 
                        switch(key){
                            case "play":
                            html += "►";
                            break;
                            case "browse":
                            html += ">";
                            break;
                        }
                        html += "</button>";
                      }
                      html += "</td>";
                      html += "</tr>";
                  }
                  html += "</table></div>";
              }
              setState("0_userdata.0.scriptData.HeosBrowseTable", html);
            });
            
            UhulaU S 2 Antworten Letzte Antwort
            0
            • W withstu

              @sveni_lee Danke. Habe es geändert in Version 1.3.3. Das Script habe ich übrigens so geschrieben, dass jeder selber sein Design hinterlegen kann. Wenn du den Text linksbündig und die Buttons rechtsbündig haben willst, musst du "text-align" bei den td Elementen hinzufügen:
              Rechtsbündig:

              html += "<td style\"text-align:right\">";
              

              Linksbündig:

              html += "<td style\"text-align:left\">";
              

              Bei mir sieht es aktuell so aus:

              on({id: 'heos.0.sources.browse_result', change: 'any'}, function (obj) {
                let data = JSON.parse(obj.state.val);
                let html = `<style>
                .heos-browse {
                    background-color: #333333;
                    color: #eaeaea;
                }
                .heos-browse table {
                    width: 100%;
                    border-collapse: collapse;
                }
                .heos-browse table, th, td {
                    border: 1px solid #929292;
                    border-width:1px 0;
                }
                .heos-browse th {
                    font-size: 2em;
                    border: 1px solid #c50000;
                    border-width: 0 0 1px 0;
                    text-align: center;
                }
                .heos-browse th,td {
                    padding: 15px;
                }
                .heos-browse-btn {
                    color: #fff;
                    background-color: Transparent;
                    background-repeat:no-repeat;
                    border: none;
                    cursor:pointer;
                    overflow: hidden;
                    outline:none;
                    margin: 0;
                    padding: 0;
                    font-size: 30px !important;
                    line-height: 30px;
                    width: 60px;
                    height: 60px;
                }
                .heos-browse-btn-multi {
                    border-right: 1px solid #929292;
                }
                .heos-browse-row-media {
              
                }
                .heos-browse-row-control {
                    color: #d60000;
                }
                .heos-browse-image {
                    white-space: nowrap;
                    padding: 0;
                    text-align: right;
                    font-size: 0;
                }
                .heos-browse-image img {
                    height: 60px;
                }
                .heos-browse-name {
                    width: 100%;
                    text-align: left;
                }
                .heos-browse-control {
                    padding: 0;
                    margin: 0;
                    white-space: nowrap;
                    font-size: 0;
                    text-align: right;
                }
                </style>`;
                if(data){
                    html += "<div class=\"heos-browse\">"
                    html += "<table>"
                    html += "<tr><th>";
                    if(data.image_url.length){
                        html += "<img src=\"" + data.image_url + "\" height=\"30px\">";
                    }
                    html += "</th><th>" + (data.name == "sources" ? "Overview" : data.name) + "</th><th></th></tr>";
                    for (let i = 0; i < data.payload.length; i++) {
                        let payload = data.payload[i];
                        html += "<tr class=\"";
                        if(payload.type == "control"){
                          html += "heos-browse-row-control";
                        } else {
                            html += "heos-browse-row-media"
                        }
                        html += "\">";
                        html += "<td class=\"heos-browse-image\"";
                        if("browse" in payload.commands){
                            html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands["browse"] +"')\"";
                        } else if(Object.keys(payload.commands).length == 1){
                            html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands[Object.keys(payload.commands)[0]] +"')\"";
                        }
                        html += ">"
                        if(payload.image_url.length){
                          html += "<img src=\"" + payload.image_url + "\">";
                        }
                        html += "</td>";
                        html += "<td class=\"heos-browse-name\"";
                        if("browse" in payload.commands){
                            html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands["browse"] +"')\"";
                        } else if(Object.keys(payload.commands).length == 1){
                            html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands[Object.keys(payload.commands)[0]] +"')\"";
                        }
                        html += ">"
                        if(payload.type == "control"){
                          switch(payload.name){
                            case "load_next":
                              html += "Next page";
                              break;
                            case "load_prev":
                              html += "Previous page";
                              break;
                            case "play_all":
                              html += "Play all";
                              break;
                            case "back":
                              html += "Back";
                              break;
                            case "sources":
                              html += "Overview";
                              break;
                          }
                        } else {
                          html += payload.name;
                        }
                        html +="</td>";
                        html += "<td class=\"heos-browse-control\">";
                        for (let key in payload.commands) {
                          let command = payload.commands[key];
                          html += "<button class=\"heos-browse-btn"
                          if(Object.keys(payload.commands).length > 1){
                              html += " heos-browse-btn-multi"
                          }
                          html += "\" onClick=\"servConn.setState('heos.0.command','" + command +"')\">" 
                          switch(key){
                              case "play":
                              html += "►";
                              break;
                              case "browse":
                              html += ">";
                              break;
                          }
                          html += "</button>";
                        }
                        html += "</td>";
                        html += "</tr>";
                    }
                    html += "</table></div>";
                }
                setState("0_userdata.0.scriptData.HeosBrowseTable", html);
              });
              
              UhulaU Offline
              UhulaU Offline
              Uhula
              schrieb am zuletzt editiert von
              #202

              @withstu Ich benutze nun auch deinen Adapter (v1.3.4) statt des Scripts. Funktioniert prima, danke für deinen Entwicklungsaufwand!

              Aus Neugier habe ich auch die neue Browse-Funktionalität getestet - auch diese funktioniert grundsätzlich prima. Drei Anmerkungen habe ich aber dazu:

              • Sortierung: Ich halte es für unglücklich die Ergebnislisten nach dem Namen zu sortieren, das ist Sache der Quelle. Sonst kommen wie unten dargestellt komische Ergebnisse heraus
              • Available-Sourcen: Hier fragst du mit einer der letzten Änderungen den available State ab und liefert nur solche zurück, die true besitzen. Der state hat aber nicht immer den korrekten Wert. Bei mir ist z.B. Amazon-Music als false gesetzt, obwohl ich darüber browsen kann (command manuell gefüllt)
              • beim Abspielen wird immer ein player-broadcast durchgeführt. Wird hierbei der jeweilige State heos.0.players.xxx.ignore_broadcast_cmd berücksichtigt?

              Hier die Sortierung der Top-Playlists von Amazon (alphabetisch korrekt, sinnhaft falsch):
              2124ffda-60ff-43ef-83e1-a4fff2fabf2d-image.png

              Ich nutze ein eigenes Script für die Navigation, nicht table-basiert:

              • die globalen Navigationsflächen kommen in eine Kopfzeile, so dass sie nicht mit wegscrollen
              • Kopfzeile mit Infos über Anzahl / geladene Zeilen
              • nur der listview-Bereich scrollt
              • nur Nutzung von Standard HTML-Symbolen, keine PNGs usw.
              • reines HTML/CSS, benötigt kein weiteres vis-ui oder MDCSS-ui

              Selbstverständlich werde ich das Script dann hier zur Verfügung stellen, wenn es fertig ist.

              Preview:
              heos_browse.gif

              Uhula - Leise und Weise
              Ex: ioBroker on Gigabyte NUC Proxmox

              S W 2 Antworten Letzte Antwort
              0
              • W withstu

                @sveni_lee Danke. Habe es geändert in Version 1.3.3. Das Script habe ich übrigens so geschrieben, dass jeder selber sein Design hinterlegen kann. Wenn du den Text linksbündig und die Buttons rechtsbündig haben willst, musst du "text-align" bei den td Elementen hinzufügen:
                Rechtsbündig:

                html += "<td style\"text-align:right\">";
                

                Linksbündig:

                html += "<td style\"text-align:left\">";
                

                Bei mir sieht es aktuell so aus:

                on({id: 'heos.0.sources.browse_result', change: 'any'}, function (obj) {
                  let data = JSON.parse(obj.state.val);
                  let html = `<style>
                  .heos-browse {
                      background-color: #333333;
                      color: #eaeaea;
                  }
                  .heos-browse table {
                      width: 100%;
                      border-collapse: collapse;
                  }
                  .heos-browse table, th, td {
                      border: 1px solid #929292;
                      border-width:1px 0;
                  }
                  .heos-browse th {
                      font-size: 2em;
                      border: 1px solid #c50000;
                      border-width: 0 0 1px 0;
                      text-align: center;
                  }
                  .heos-browse th,td {
                      padding: 15px;
                  }
                  .heos-browse-btn {
                      color: #fff;
                      background-color: Transparent;
                      background-repeat:no-repeat;
                      border: none;
                      cursor:pointer;
                      overflow: hidden;
                      outline:none;
                      margin: 0;
                      padding: 0;
                      font-size: 30px !important;
                      line-height: 30px;
                      width: 60px;
                      height: 60px;
                  }
                  .heos-browse-btn-multi {
                      border-right: 1px solid #929292;
                  }
                  .heos-browse-row-media {
                
                  }
                  .heos-browse-row-control {
                      color: #d60000;
                  }
                  .heos-browse-image {
                      white-space: nowrap;
                      padding: 0;
                      text-align: right;
                      font-size: 0;
                  }
                  .heos-browse-image img {
                      height: 60px;
                  }
                  .heos-browse-name {
                      width: 100%;
                      text-align: left;
                  }
                  .heos-browse-control {
                      padding: 0;
                      margin: 0;
                      white-space: nowrap;
                      font-size: 0;
                      text-align: right;
                  }
                  </style>`;
                  if(data){
                      html += "<div class=\"heos-browse\">"
                      html += "<table>"
                      html += "<tr><th>";
                      if(data.image_url.length){
                          html += "<img src=\"" + data.image_url + "\" height=\"30px\">";
                      }
                      html += "</th><th>" + (data.name == "sources" ? "Overview" : data.name) + "</th><th></th></tr>";
                      for (let i = 0; i < data.payload.length; i++) {
                          let payload = data.payload[i];
                          html += "<tr class=\"";
                          if(payload.type == "control"){
                            html += "heos-browse-row-control";
                          } else {
                              html += "heos-browse-row-media"
                          }
                          html += "\">";
                          html += "<td class=\"heos-browse-image\"";
                          if("browse" in payload.commands){
                              html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands["browse"] +"')\"";
                          } else if(Object.keys(payload.commands).length == 1){
                              html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands[Object.keys(payload.commands)[0]] +"')\"";
                          }
                          html += ">"
                          if(payload.image_url.length){
                            html += "<img src=\"" + payload.image_url + "\">";
                          }
                          html += "</td>";
                          html += "<td class=\"heos-browse-name\"";
                          if("browse" in payload.commands){
                              html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands["browse"] +"')\"";
                          } else if(Object.keys(payload.commands).length == 1){
                              html += " onClick=\"servConn.setState('heos.0.command','" + payload.commands[Object.keys(payload.commands)[0]] +"')\"";
                          }
                          html += ">"
                          if(payload.type == "control"){
                            switch(payload.name){
                              case "load_next":
                                html += "Next page";
                                break;
                              case "load_prev":
                                html += "Previous page";
                                break;
                              case "play_all":
                                html += "Play all";
                                break;
                              case "back":
                                html += "Back";
                                break;
                              case "sources":
                                html += "Overview";
                                break;
                            }
                          } else {
                            html += payload.name;
                          }
                          html +="</td>";
                          html += "<td class=\"heos-browse-control\">";
                          for (let key in payload.commands) {
                            let command = payload.commands[key];
                            html += "<button class=\"heos-browse-btn"
                            if(Object.keys(payload.commands).length > 1){
                                html += " heos-browse-btn-multi"
                            }
                            html += "\" onClick=\"servConn.setState('heos.0.command','" + command +"')\">" 
                            switch(key){
                                case "play":
                                html += "►";
                                break;
                                case "browse":
                                html += ">";
                                break;
                            }
                            html += "</button>";
                          }
                          html += "</td>";
                          html += "</tr>";
                      }
                      html += "</table></div>";
                  }
                  setState("0_userdata.0.scriptData.HeosBrowseTable", html);
                });
                
                S Offline
                S Offline
                sveni_lee
                schrieb am zuletzt editiert von
                #203

                @withstu sagte in [Vorlage] Denon HEOS Script:

                danke für die schnelle Umsetzung.
                ich habe versucht nur die Buttons rechtsbündig zu bekommen aber wenn ich Zeile 93 wie folgt änder

                html += "<td style\"text-align:right\">";
                

                hat das keine Auswirkung.

                und nebenbei gefragt, weiß Jemand wie Heos eine Datenbank ausließt? nach welchen Kriterien wird denn sortiert?

                1 Antwort Letzte Antwort
                0
                • UhulaU Uhula

                  @withstu Ich benutze nun auch deinen Adapter (v1.3.4) statt des Scripts. Funktioniert prima, danke für deinen Entwicklungsaufwand!

                  Aus Neugier habe ich auch die neue Browse-Funktionalität getestet - auch diese funktioniert grundsätzlich prima. Drei Anmerkungen habe ich aber dazu:

                  • Sortierung: Ich halte es für unglücklich die Ergebnislisten nach dem Namen zu sortieren, das ist Sache der Quelle. Sonst kommen wie unten dargestellt komische Ergebnisse heraus
                  • Available-Sourcen: Hier fragst du mit einer der letzten Änderungen den available State ab und liefert nur solche zurück, die true besitzen. Der state hat aber nicht immer den korrekten Wert. Bei mir ist z.B. Amazon-Music als false gesetzt, obwohl ich darüber browsen kann (command manuell gefüllt)
                  • beim Abspielen wird immer ein player-broadcast durchgeführt. Wird hierbei der jeweilige State heos.0.players.xxx.ignore_broadcast_cmd berücksichtigt?

                  Hier die Sortierung der Top-Playlists von Amazon (alphabetisch korrekt, sinnhaft falsch):
                  2124ffda-60ff-43ef-83e1-a4fff2fabf2d-image.png

                  Ich nutze ein eigenes Script für die Navigation, nicht table-basiert:

                  • die globalen Navigationsflächen kommen in eine Kopfzeile, so dass sie nicht mit wegscrollen
                  • Kopfzeile mit Infos über Anzahl / geladene Zeilen
                  • nur der listview-Bereich scrollt
                  • nur Nutzung von Standard HTML-Symbolen, keine PNGs usw.
                  • reines HTML/CSS, benötigt kein weiteres vis-ui oder MDCSS-ui

                  Selbstverständlich werde ich das Script dann hier zur Verfügung stellen, wenn es fertig ist.

                  Preview:
                  heos_browse.gif

                  S Offline
                  S Offline
                  sveni_lee
                  schrieb am zuletzt editiert von
                  #204

                  @Uhula

                  Die Sortierung war glaube ich meine Idee.
                  Meine Musik auf dem NAS hat eine klare Ordnerstruktur und trotzdem wird alles durcheinander gewürfelt ausgegeben. ich habe noch nicht herausfinden können wonach sortiert wird.
                  Auch jetzt noch habe ich das Problem das zwar die einzelnen seiten korrekt sortiert sind aber ebeb nicht das große ganze...

                  UhulaU 1 Antwort Letzte Antwort
                  0
                  • S sveni_lee

                    @Uhula

                    Die Sortierung war glaube ich meine Idee.
                    Meine Musik auf dem NAS hat eine klare Ordnerstruktur und trotzdem wird alles durcheinander gewürfelt ausgegeben. ich habe noch nicht herausfinden können wonach sortiert wird.
                    Auch jetzt noch habe ich das Problem das zwar die einzelnen seiten korrekt sortiert sind aber ebeb nicht das große ganze...

                    UhulaU Offline
                    UhulaU Offline
                    Uhula
                    schrieb am zuletzt editiert von
                    #205

                    @sveni_lee Und genau deswegen ist es die Sache des Servers (Quelle) die Daten zu sortieren, nicht die des Clients - denn der kennt nur einen Ausschnitt. Wenn du deine Daten z.B. auf einer NAS liegen hast, dann wird dort ein Mediaserver laufen. Dort müsstest du die Standard-Sortierung einstellen können.

                    Uhula - Leise und Weise
                    Ex: ioBroker on Gigabyte NUC Proxmox

                    S 1 Antwort Letzte Antwort
                    0
                    • UhulaU Uhula

                      @withstu Ich benutze nun auch deinen Adapter (v1.3.4) statt des Scripts. Funktioniert prima, danke für deinen Entwicklungsaufwand!

                      Aus Neugier habe ich auch die neue Browse-Funktionalität getestet - auch diese funktioniert grundsätzlich prima. Drei Anmerkungen habe ich aber dazu:

                      • Sortierung: Ich halte es für unglücklich die Ergebnislisten nach dem Namen zu sortieren, das ist Sache der Quelle. Sonst kommen wie unten dargestellt komische Ergebnisse heraus
                      • Available-Sourcen: Hier fragst du mit einer der letzten Änderungen den available State ab und liefert nur solche zurück, die true besitzen. Der state hat aber nicht immer den korrekten Wert. Bei mir ist z.B. Amazon-Music als false gesetzt, obwohl ich darüber browsen kann (command manuell gefüllt)
                      • beim Abspielen wird immer ein player-broadcast durchgeführt. Wird hierbei der jeweilige State heos.0.players.xxx.ignore_broadcast_cmd berücksichtigt?

                      Hier die Sortierung der Top-Playlists von Amazon (alphabetisch korrekt, sinnhaft falsch):
                      2124ffda-60ff-43ef-83e1-a4fff2fabf2d-image.png

                      Ich nutze ein eigenes Script für die Navigation, nicht table-basiert:

                      • die globalen Navigationsflächen kommen in eine Kopfzeile, so dass sie nicht mit wegscrollen
                      • Kopfzeile mit Infos über Anzahl / geladene Zeilen
                      • nur der listview-Bereich scrollt
                      • nur Nutzung von Standard HTML-Symbolen, keine PNGs usw.
                      • reines HTML/CSS, benötigt kein weiteres vis-ui oder MDCSS-ui

                      Selbstverständlich werde ich das Script dann hier zur Verfügung stellen, wenn es fertig ist.

                      Preview:
                      heos_browse.gif

                      W Offline
                      W Offline
                      withstu
                      schrieb am zuletzt editiert von withstu
                      #206

                      @Uhula Ich habe jetzt die Sortierung und den available check wieder rausgenommen (1.3.4). War mir nicht bewusst, dass das flag nicht so gut funktioniert. Hab es jetzt ins JSON mit reingepackt, sodass man im VIS Script filtern könnte. Von der Sortierung hatte ich mir eigentlich mehr erhofft, aber wenn man sich mal alle Songs im NAS anzeigen lässt und sich durch die Pages klickt, merkt man sehr schnell, dass HEOS oder die Source die Daten unsortiert schickt. Wer eine Sortierung haben möchte, kann ja immer noch im VIS Script sortieren.

                      Zum player-broadcast: Wie du richtig erkannt hast, kann man einen Player mit dem State ignore_broadcast_cmd aus dem Broadcast rausnehmen (bei mir hab ich das z.B. für den AV-Receiver aktiviert). Aber mir ist gerade aufgefallen, dass die Play Commands aus der Oberfläche an wirklich alle Player geschickt werden (außer die mit dem Ignore). Das führt bei Gruppen dazu, dass für jeden Player der Gruppe die Playlist gestartet wird und es zu Beginn stottert. Deswegen habe ich auf globaler Ebene noch das Prefix "leader/[cmd]" eingeführt. Wenn also ein Player in einer Gruppe ist, wird der Command nur an den Leader geschickt. Leader ist auch ein Player, der in keiner Gruppe ist.

                      Dein Script sieht ja jetzt schon klasse aus 🙂

                      UhulaU 1 Antwort Letzte Antwort
                      0
                      • W withstu

                        @Uhula Ich habe jetzt die Sortierung und den available check wieder rausgenommen (1.3.4). War mir nicht bewusst, dass das flag nicht so gut funktioniert. Hab es jetzt ins JSON mit reingepackt, sodass man im VIS Script filtern könnte. Von der Sortierung hatte ich mir eigentlich mehr erhofft, aber wenn man sich mal alle Songs im NAS anzeigen lässt und sich durch die Pages klickt, merkt man sehr schnell, dass HEOS oder die Source die Daten unsortiert schickt. Wer eine Sortierung haben möchte, kann ja immer noch im VIS Script sortieren.

                        Zum player-broadcast: Wie du richtig erkannt hast, kann man einen Player mit dem State ignore_broadcast_cmd aus dem Broadcast rausnehmen (bei mir hab ich das z.B. für den AV-Receiver aktiviert). Aber mir ist gerade aufgefallen, dass die Play Commands aus der Oberfläche an wirklich alle Player geschickt werden (außer die mit dem Ignore). Das führt bei Gruppen dazu, dass für jeden Player der Gruppe die Playlist gestartet wird und es zu Beginn stottert. Deswegen habe ich auf globaler Ebene noch das Prefix "leader/[cmd]" eingeführt. Wenn also ein Player in einer Gruppe ist, wird der Command nur an den Leader geschickt. Leader ist auch ein Player, der in keiner Gruppe ist.

                        Dein Script sieht ja jetzt schon klasse aus 🙂

                        UhulaU Offline
                        UhulaU Offline
                        Uhula
                        schrieb am zuletzt editiert von
                        #207

                        @withstu Danke für die Rück-Änderungen.

                        Das mit den Playern werde ich bei mir anders lösen. Ich werde neben dem 0_userdata.heos.browse_result_html-State noch ein 0_userdata.heos.browse_result_player führen und mir dort via vis die PIDs der Player eintragen, welche die play-Befehle erhalten sollen. Im Script patch ich dann den command-Befehl und sorge dafür, dass die play-Befehle dann nur in die command-States der Player und nicht in den globalen command-State geschrieben werden.

                        Das hat auch den Vorteil, dass man die Browse-View nur einmal haben muss und vorher beim jqui-container-HTML-View vor dem Öffnen des Browser-Views noch automatisch die korrekten PIDs setzen kann. Müsste funktionieren, teste ich morgen mal.

                        Hier ein Beispiel:
                        a132f94e-aae3-4664-ae1d-addbb8cb85c2-image.png

                        Uhula - Leise und Weise
                        Ex: ioBroker on Gigabyte NUC Proxmox

                        1 Antwort Letzte Antwort
                        0
                        • UhulaU Uhula

                          @sveni_lee Und genau deswegen ist es die Sache des Servers (Quelle) die Daten zu sortieren, nicht die des Clients - denn der kennt nur einen Ausschnitt. Wenn du deine Daten z.B. auf einer NAS liegen hast, dann wird dort ein Mediaserver laufen. Dort müsstest du die Standard-Sortierung einstellen können.

                          S Offline
                          S Offline
                          sveni_lee
                          schrieb am zuletzt editiert von
                          #208

                          @Uhula
                          Ich habe alle Daten auf den NAS liegen aber nicht extra einen Mediaserver. Als Frontend fungiert im Normalfall KODI das baut eine eigene Datenbank auf aber selbst wenn ich dort durch die Ordnerstruktur browse so wie in HEOS auch bekomme ich bei KODI eine „saubere“ Anzeige.
                          Ich verstehe halt nicht wie sich HEOS die Daten aus einer Netzwerkfreigabe holt...

                          UhulaU 1 Antwort Letzte Antwort
                          0
                          • S sveni_lee

                            @Uhula
                            Ich habe alle Daten auf den NAS liegen aber nicht extra einen Mediaserver. Als Frontend fungiert im Normalfall KODI das baut eine eigene Datenbank auf aber selbst wenn ich dort durch die Ordnerstruktur browse so wie in HEOS auch bekomme ich bei KODI eine „saubere“ Anzeige.
                            Ich verstehe halt nicht wie sich HEOS die Daten aus einer Netzwerkfreigabe holt...

                            UhulaU Offline
                            UhulaU Offline
                            Uhula
                            schrieb am zuletzt editiert von
                            #209

                            Anbei ein kleines Script um die browse_results des HEOS Adapters in einer Liste darstellen zu können. Im folgenden Beispiel ist es im modalen Dialog zu sehen (die am Anfang zu sehenden Cards usw. gehören nicht dazu, die entstammen dem MDCSS). Das Script benötigt keine weiteren ui's sondern erzeugt reines HTML/CSS. Viel Freude - und danke an @withstu für seinen Adapter.
                            heos_browse.gif

                            HEOS Media-Browser-Script

                            Der HEOS Adapter (https://github.com/withstu/ioBroker.heos) erlaubt neben der Steuerung der HEOS Geräte auch das
                            Navigieren durch die Musikquellen. Allerdings muss hierzu noch ein serverseitiges Script laufen, welches die
                            Navigationsergebnisse in eine HTML Darstellung überträgt, so dass diese in einem basic-string(unescaped)-Widget
                            darstellbar und bedienbar werden.

                            Genau macht dieses Script.

                            Installation

                            • HEOS-Adapter installieren und starten (https://github.com/withstu/ioBroker.heos)
                            • HTML-State "0_userdata.0.heos.browse_result_html" als Zeichenkette anlegen (alternativ eigener State, dann in der Konfiguration anpassen)
                            • dieses Script im Admin unter Skripte als neues Script hinzufügen.
                            • dieses Script starten
                            • in der ioBroker-vis ein basic-string(unescaped)-Widget in einem View einfügen, den HTML-State zuweisen
                            • View ausführen

                            (c) Uhula, MIT License, no warranty, use on your own risc

                            Script: heos_browse.js

                            Uhula - Leise und Weise
                            Ex: ioBroker on Gigabyte NUC Proxmox

                            W C foxriver76F 4 Antworten Letzte Antwort
                            0
                            • S Offline
                              S Offline
                              sveni_lee
                              schrieb am zuletzt editiert von
                              #210

                              ich habe mir jetzt mal den minidlna auf meinem "NAS" installiert und tatsächlich hat sich damit die Problematik mit dem Sortieren erledigt. Die navigation ist nun sehr intuitiv .

                              Super Arbeit von beiden. Endlich kann ich meine Musiksammlung (47.000 Titel) vernüftig pro Raum steuern.

                              Danke

                              1 Antwort Letzte Antwort
                              0
                              • UhulaU Uhula

                                Anbei ein kleines Script um die browse_results des HEOS Adapters in einer Liste darstellen zu können. Im folgenden Beispiel ist es im modalen Dialog zu sehen (die am Anfang zu sehenden Cards usw. gehören nicht dazu, die entstammen dem MDCSS). Das Script benötigt keine weiteren ui's sondern erzeugt reines HTML/CSS. Viel Freude - und danke an @withstu für seinen Adapter.
                                heos_browse.gif

                                HEOS Media-Browser-Script

                                Der HEOS Adapter (https://github.com/withstu/ioBroker.heos) erlaubt neben der Steuerung der HEOS Geräte auch das
                                Navigieren durch die Musikquellen. Allerdings muss hierzu noch ein serverseitiges Script laufen, welches die
                                Navigationsergebnisse in eine HTML Darstellung überträgt, so dass diese in einem basic-string(unescaped)-Widget
                                darstellbar und bedienbar werden.

                                Genau macht dieses Script.

                                Installation

                                • HEOS-Adapter installieren und starten (https://github.com/withstu/ioBroker.heos)
                                • HTML-State "0_userdata.0.heos.browse_result_html" als Zeichenkette anlegen (alternativ eigener State, dann in der Konfiguration anpassen)
                                • dieses Script im Admin unter Skripte als neues Script hinzufügen.
                                • dieses Script starten
                                • in der ioBroker-vis ein basic-string(unescaped)-Widget in einem View einfügen, den HTML-State zuweisen
                                • View ausführen

                                (c) Uhula, MIT License, no warranty, use on your own risc

                                Script: heos_browse.js

                                W Offline
                                W Offline
                                withstu
                                schrieb am zuletzt editiert von
                                #211

                                @Uhula Ich habe gerade Version 1.4.0 veröffentlich. Darin habe ich auch einige Anregungen aus deinem Script übernommen:

                                • Konfiguration der Warteschlangenoptionen (aid Parameter der HEOS CLI)
                                • Neue Kommando Gruppe scope/[cmd]. Das Verhalten kann über die Adaptereinstellungen gesteuert werden. Zur Auswahl steht, dass Kommandos an alle Player, an alle Leader/Non-Group Player oder an die PIDs in dem neuen State command_scope_pid gesendet werden. Der State command_scope_pid entspricht deinem browse_result_player und sollte eine kommaseparierte Liste der PIDs enthalten. Dadurch kannst du dein Script ein bisschen aufräumen. Denn das Senden der Kommandos an die entsprechenden Player wird direkt vom Adapter übernommen.
                                1 Antwort Letzte Antwort
                                0
                                • UhulaU Uhula

                                  Anbei ein kleines Script um die browse_results des HEOS Adapters in einer Liste darstellen zu können. Im folgenden Beispiel ist es im modalen Dialog zu sehen (die am Anfang zu sehenden Cards usw. gehören nicht dazu, die entstammen dem MDCSS). Das Script benötigt keine weiteren ui's sondern erzeugt reines HTML/CSS. Viel Freude - und danke an @withstu für seinen Adapter.
                                  heos_browse.gif

                                  HEOS Media-Browser-Script

                                  Der HEOS Adapter (https://github.com/withstu/ioBroker.heos) erlaubt neben der Steuerung der HEOS Geräte auch das
                                  Navigieren durch die Musikquellen. Allerdings muss hierzu noch ein serverseitiges Script laufen, welches die
                                  Navigationsergebnisse in eine HTML Darstellung überträgt, so dass diese in einem basic-string(unescaped)-Widget
                                  darstellbar und bedienbar werden.

                                  Genau macht dieses Script.

                                  Installation

                                  • HEOS-Adapter installieren und starten (https://github.com/withstu/ioBroker.heos)
                                  • HTML-State "0_userdata.0.heos.browse_result_html" als Zeichenkette anlegen (alternativ eigener State, dann in der Konfiguration anpassen)
                                  • dieses Script im Admin unter Skripte als neues Script hinzufügen.
                                  • dieses Script starten
                                  • in der ioBroker-vis ein basic-string(unescaped)-Widget in einem View einfügen, den HTML-State zuweisen
                                  • View ausführen

                                  (c) Uhula, MIT License, no warranty, use on your own risc

                                  Script: heos_browse.js

                                  W Offline
                                  W Offline
                                  withstu
                                  schrieb am zuletzt editiert von
                                  #212

                                  @Uhula Wenn man übrigens im command_scope_pid nichts einträgt, wird der Command an alle Player geschickt. Hab so für jeden Player nen Browse Dialog gebaut und dann nochmal einen globalen, der beim Öffnen einfach einen Leerstring in den State setzt. So kann man den Browse Dialog für einzelne Player und für alle Player benutzen. Zusätzlich hab ich mir noch für jeden Player einen Dialog für die Queue gebastelt, welche die 50 nächsten Lieder anzeigt:

                                  on({id: '0_userdata.0.heos.queue_pid', change: 'any'}, function (obj) {
                                      let pid = obj.state.val;
                                      let data = JSON.parse(getState("heos.0.players." + pid + ".queue").val);
                                      let html = `<style>
                                      .heos-queue {
                                          background-color: #333333;
                                          color: #eaeaea;
                                          height: 100%;
                                          width: 100%;
                                          position: absolute;
                                          overflow: auto;
                                      }
                                      .heos-queue table {
                                          width: 100%;
                                          border-collapse: collapse;
                                      }
                                      .heos-queue table, 
                                      .heos-queue th, 
                                      .heos-queue td {
                                          border: 1px solid #929292;
                                          border-width:1px 0;
                                      }
                                      .heos-queue th {
                                          font-size: 2em;
                                          border: 1px solid #c50000;
                                          border-width: 0 0 1px 0;
                                          text-align: center;
                                      }
                                      .heos-queue th {
                                          padding: 15px;
                                          height: 60px;
                                      }
                                      .heos-queue td {
                                          padding: 5px;
                                          height: 60px
                                      }
                                      .heos-queue-btn {
                                          color: #fff;
                                          background-color: Transparent;
                                          background-repeat:no-repeat;
                                          border: none;
                                          cursor:pointer;
                                          overflow: hidden;
                                          outline:none;
                                          margin: 0 !important;
                                          padding: 0 !important;
                                          font-size: 30px !important;
                                          line-height: 30px;
                                          width: 60px;
                                          height: 60px;
                                      }
                                      .heos-queue-btn-multi {
                                          border-right: 1px solid #929292;
                                      }
                                      .heos-queue-row-media {
                                          //cursor: pointer;
                                      }
                                      .heos-queue-row-control {
                                          color: #d60000;
                                          //cursor: pointer;
                                      }
                                      .heos-queue-image {
                                          white-space: nowrap;
                                          padding: 0 !important;
                                          text-align: right;
                                          font-size: 0;
                                      }
                                      .heos-queue-image img {
                                          height: 60px;
                                      }
                                      .heos-queue-name {
                                          width: 100%;
                                          text-align: left;
                                      }
                                      .heos-queue-control {
                                          padding: 0 !important;
                                          margin: 0 !important;
                                          white-space: nowrap;
                                          font-size: 0;
                                          text-align: right;
                                      }
                                      </style>`;
                                      if(data){
                                          html += "<div class=\"heos-queue\">"
                                          html += "<table>"
                                          html += "<tr><th>";
                                          html += "</th><th>Queue</th><th></th></tr>";
                                          for (var qid in data) {
                                              let payload = data[qid];
                                              html += "<tr class=\"heos-queue-row-media\">";
                                              html += "<td class=\"heos-queue-image\">";
                                              if(payload.image_url.length){
                                                html += "<img src=\"" + payload.image_url + "\">";
                                              }
                                              html += "</td>";
                                              html += "<td class=\"heos-queue-name\">";
                                              let meta = [];
                                              if(payload.song){
                                                meta.push(payload.song);
                                              }
                                              if(payload.artist){
                                                meta.push(payload.artist);
                                              }
                                              if(payload.album){
                                                meta.push(payload.album);
                                              }
                                              if(meta.length){
                                                html += meta.join(' | ');
                                              }
                                              html +="</td>";
                                              html += "<td class=\"heos-queue-control\">";
                                              html += "</td>";
                                              html += "</tr>";
                                          }
                                          html += "</table></div>";
                                      }
                                      setState("0_userdata.0.heos.queue_html", html);
                                    });
                                  
                                  H 1 Antwort Letzte Antwort
                                  0
                                  • W withstu

                                    @Uhula Wenn man übrigens im command_scope_pid nichts einträgt, wird der Command an alle Player geschickt. Hab so für jeden Player nen Browse Dialog gebaut und dann nochmal einen globalen, der beim Öffnen einfach einen Leerstring in den State setzt. So kann man den Browse Dialog für einzelne Player und für alle Player benutzen. Zusätzlich hab ich mir noch für jeden Player einen Dialog für die Queue gebastelt, welche die 50 nächsten Lieder anzeigt:

                                    on({id: '0_userdata.0.heos.queue_pid', change: 'any'}, function (obj) {
                                        let pid = obj.state.val;
                                        let data = JSON.parse(getState("heos.0.players." + pid + ".queue").val);
                                        let html = `<style>
                                        .heos-queue {
                                            background-color: #333333;
                                            color: #eaeaea;
                                            height: 100%;
                                            width: 100%;
                                            position: absolute;
                                            overflow: auto;
                                        }
                                        .heos-queue table {
                                            width: 100%;
                                            border-collapse: collapse;
                                        }
                                        .heos-queue table, 
                                        .heos-queue th, 
                                        .heos-queue td {
                                            border: 1px solid #929292;
                                            border-width:1px 0;
                                        }
                                        .heos-queue th {
                                            font-size: 2em;
                                            border: 1px solid #c50000;
                                            border-width: 0 0 1px 0;
                                            text-align: center;
                                        }
                                        .heos-queue th {
                                            padding: 15px;
                                            height: 60px;
                                        }
                                        .heos-queue td {
                                            padding: 5px;
                                            height: 60px
                                        }
                                        .heos-queue-btn {
                                            color: #fff;
                                            background-color: Transparent;
                                            background-repeat:no-repeat;
                                            border: none;
                                            cursor:pointer;
                                            overflow: hidden;
                                            outline:none;
                                            margin: 0 !important;
                                            padding: 0 !important;
                                            font-size: 30px !important;
                                            line-height: 30px;
                                            width: 60px;
                                            height: 60px;
                                        }
                                        .heos-queue-btn-multi {
                                            border-right: 1px solid #929292;
                                        }
                                        .heos-queue-row-media {
                                            //cursor: pointer;
                                        }
                                        .heos-queue-row-control {
                                            color: #d60000;
                                            //cursor: pointer;
                                        }
                                        .heos-queue-image {
                                            white-space: nowrap;
                                            padding: 0 !important;
                                            text-align: right;
                                            font-size: 0;
                                        }
                                        .heos-queue-image img {
                                            height: 60px;
                                        }
                                        .heos-queue-name {
                                            width: 100%;
                                            text-align: left;
                                        }
                                        .heos-queue-control {
                                            padding: 0 !important;
                                            margin: 0 !important;
                                            white-space: nowrap;
                                            font-size: 0;
                                            text-align: right;
                                        }
                                        </style>`;
                                        if(data){
                                            html += "<div class=\"heos-queue\">"
                                            html += "<table>"
                                            html += "<tr><th>";
                                            html += "</th><th>Queue</th><th></th></tr>";
                                            for (var qid in data) {
                                                let payload = data[qid];
                                                html += "<tr class=\"heos-queue-row-media\">";
                                                html += "<td class=\"heos-queue-image\">";
                                                if(payload.image_url.length){
                                                  html += "<img src=\"" + payload.image_url + "\">";
                                                }
                                                html += "</td>";
                                                html += "<td class=\"heos-queue-name\">";
                                                let meta = [];
                                                if(payload.song){
                                                  meta.push(payload.song);
                                                }
                                                if(payload.artist){
                                                  meta.push(payload.artist);
                                                }
                                                if(payload.album){
                                                  meta.push(payload.album);
                                                }
                                                if(meta.length){
                                                  html += meta.join(' | ');
                                                }
                                                html +="</td>";
                                                html += "<td class=\"heos-queue-control\">";
                                                html += "</td>";
                                                html += "</tr>";
                                            }
                                            html += "</table></div>";
                                        }
                                        setState("0_userdata.0.heos.queue_html", html);
                                      });
                                    
                                    H Offline
                                    H Offline
                                    hotze78
                                    schrieb am zuletzt editiert von hotze78
                                    #213

                                    @withstu
                                    Browse Sources 1.4.0 wie aktuell in Git funktioniert bei mir nicht. Oder ich weis nicht wie einbinden in Vis. Ich sehe kein anderen Weg als über Html und genau da habe ich keine html Ausgabe nur deren daten. Wert heos.0.sources.browse_result:

                                    {"name":"sources","image_url":"","parameter":{},"payload":[{"name":"Amazon","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/amazon.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=13"}},{"name":"Deezer","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/deezer.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=5"}},{"name":"Napster","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/napster.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=6"}},{"name":"SoundCloud","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/soundcloud.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=9"}},{"name":"Tidal","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/tidal.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=10"}},{"name":"TuneIn","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/tunein.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=3"}},{"name":"Local Music","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_servers.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1024"}},{"name":"Playlists","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_playlists.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1025"}},{"name":"History","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_history.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1026"}},{"name":"AUX Input","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_aux.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1027"}},{"name":"Favorites","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_favorites.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1028"}}]}
                                    

                                    Uhula Browser habe ich aktuell in Gebrauch. Ich habs sogar inklusive player ID hinbekommen was ich cool finde.

                                    • Gibt es eine Möglichkeit unbenutze in HEOS Quellen-Übersicht auszublenden?
                                    • Eine möglichkeit einen Bestimmten einstiegspunkt in Browse zu generieren. Also zB von Favoriten zu Playlist ist es ja kein Problem mit dem generate. Wenn ich aber in Lokalen Medien Bestimmten Ordner gleich anpeilen möchte. Anwendungszenario User A in order A User B Ordner B
                                    • Die Bilder Lokal Abspeichern von jeweils https://production.ws.skyegloup.com:443/media/images/service

                                    Euch Danke, und richtet ein Spendenkonto ein.

                                    W 1 Antwort Letzte Antwort
                                    0
                                    • H hotze78

                                      @withstu
                                      Browse Sources 1.4.0 wie aktuell in Git funktioniert bei mir nicht. Oder ich weis nicht wie einbinden in Vis. Ich sehe kein anderen Weg als über Html und genau da habe ich keine html Ausgabe nur deren daten. Wert heos.0.sources.browse_result:

                                      {"name":"sources","image_url":"","parameter":{},"payload":[{"name":"Amazon","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/amazon.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=13"}},{"name":"Deezer","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/deezer.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=5"}},{"name":"Napster","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/napster.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=6"}},{"name":"SoundCloud","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/soundcloud.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=9"}},{"name":"Tidal","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/tidal.png","type":"media","available":false,"commands":{"browse":"browse/browse?sid=10"}},{"name":"TuneIn","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/tunein.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=3"}},{"name":"Local Music","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_servers.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1024"}},{"name":"Playlists","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_playlists.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1025"}},{"name":"History","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_history.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1026"}},{"name":"AUX Input","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_aux.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1027"}},{"name":"Favorites","image_url":"https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_favorites.png","type":"media","available":true,"commands":{"browse":"browse/browse?sid=1028"}}]}
                                      

                                      Uhula Browser habe ich aktuell in Gebrauch. Ich habs sogar inklusive player ID hinbekommen was ich cool finde.

                                      • Gibt es eine Möglichkeit unbenutze in HEOS Quellen-Übersicht auszublenden?
                                      • Eine möglichkeit einen Bestimmten einstiegspunkt in Browse zu generieren. Also zB von Favoriten zu Playlist ist es ja kein Problem mit dem generate. Wenn ich aber in Lokalen Medien Bestimmten Ordner gleich anpeilen möchte. Anwendungszenario User A in order A User B Ordner B
                                      • Die Bilder Lokal Abspeichern von jeweils https://production.ws.skyegloup.com:443/media/images/service

                                      Euch Danke, und richtet ein Spendenkonto ein.

                                      W Offline
                                      W Offline
                                      withstu
                                      schrieb am zuletzt editiert von withstu
                                      #214

                                      @hotze78 Das HTML Script brauchst du nach wie vor bei Version 1.4.0. In diesem kannst du dann auch Einträge ausblenden. Zu den Einstiegspunkten musst du dir nur ein Script basteln, welches den passenden Browse Befehl in den command state packt.

                                      Übrigens in der Version 1.5.2 hab ich jetzt noch tts hinzugefügt. Ist zwar nicht optimal, aber ich glaube besser geht es mit der HEOS API nicht. Den SayIt Adapter habe ich auch angepasst und einen PR gestellt: https://github.com/withstu/ioBroker.sayit

                                      H 1 Antwort Letzte Antwort
                                      0
                                      • W withstu

                                        @hotze78 Das HTML Script brauchst du nach wie vor bei Version 1.4.0. In diesem kannst du dann auch Einträge ausblenden. Zu den Einstiegspunkten musst du dir nur ein Script basteln, welches den passenden Browse Befehl in den command state packt.

                                        Übrigens in der Version 1.5.2 hab ich jetzt noch tts hinzugefügt. Ist zwar nicht optimal, aber ich glaube besser geht es mit der HEOS API nicht. Den SayIt Adapter habe ich auch angepasst und einen PR gestellt: https://github.com/withstu/ioBroker.sayit

                                        H Offline
                                        H Offline
                                        hotze78
                                        schrieb am zuletzt editiert von hotze78
                                        #215

                                        @withstu
                                        Klar, ich meine auch das browse Scribt von der aktuellen git. Bei mir wird damit einfach keine html erzeugt. Dies vom letzten Post wird damit erzeugt. Es scheint mir, das dies die JSON daten sind.

                                        W 1 Antwort Letzte Antwort
                                        0
                                        • H hotze78

                                          @withstu
                                          Klar, ich meine auch das browse Scribt von der aktuellen git. Bei mir wird damit einfach keine html erzeugt. Dies vom letzten Post wird damit erzeugt. Es scheint mir, das dies die JSON daten sind.

                                          W Offline
                                          W Offline
                                          withstu
                                          schrieb am zuletzt editiert von
                                          #216

                                          @hotze78 Gibt es denn irgendeine Fehlermeldung? Bei mir funktioniert es nach wie vor...

                                          Übrigens ich habe gerade mal den Material UI Adapter ausprobiert. Damit das Player Widget automatisch angezeigt wird muss die Rolle vom Player State "state_simple" von euch von "media.state_simple" zu "media.state" geändert werden.

                                          H 2 Antworten Letzte Antwort
                                          0
                                          Antworten
                                          • In einem neuen Thema antworten
                                          Anmelden zum Antworten
                                          • Älteste zuerst
                                          • Neuste zuerst
                                          • Meiste Stimmen


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          745

                                          Online

                                          32.4k

                                          Benutzer

                                          81.4k

                                          Themen

                                          1.3m

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

                                          • Du hast noch kein Konto? Registrieren

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