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.1k

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

  • 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.
  • P Offline
    P Offline
    Postmymind
    schrieb am zuletzt editiert von
    #12

    Danke! Ich werde mal testen sobald ich Zuhause bin. Erreichen möchte ich z.B., dass ich über verschiedene Buttons und deren "States" im Haus (ob Hue Dimmer Switch o.Ä.) Gruppierungen, Quellenauswahl und Playstate triggern kann. Ich werde mal mit den 7 vorhandenen Heos (1x Link, 6x Heos 3/5) testen. Danke schon mal

    @Brati:

    @Postymind

    Die Gruppen solltest du gemäß CLI Protokoll mit den Player PID setzen können:

    This command is used to perform the following actions:
    
    Create new group:
    Creates new group. First player id in the list is group leader.
    Ex: heos://group/set_group?pid=3,1,4Modify existing group members:
    
    Adds or delete players from the group. First player id should be the group leader id.
    Ex: heos://group/set_group?pid=3,1,5
    
    Ungroup all players in the group
    Ungroup players. Player id (pid) should be the group leader id.
    Ex: heos://group/set_group?pid=3
    
    Command: heos://group/set_group?pid=player_id_leader, player_id_member_1,…,player_id_member_n
    

    Und das dann im "command" State übergeben. Habe es aber noch nicht getestet. Mein AVR mit 3 Zonen hat nur eine PID und dann gibt es nur eine 2. Box…

    Grüße

    Brati `

    1 Antwort Letzte Antwort
    0
    • P Offline
      P Offline
      Postmymind
      schrieb am zuletzt editiert von
      #13

      Funktioniert leider nicht. Direkt über Telnet funktioniert die Gruppierung aber über die Kommandozeile des Scripts passiert leider nichts.

      Hat sonst noch jemand weitere Ideen, wie man das lösen könnte oder ob man den Befehl über "Command" des Scripts anders senden muss?

      1 Antwort Letzte Antwort
      0
      • S Offline
        S Offline
        spielberger32
        schrieb am zuletzt editiert von
        #14

        Probier mal set_group?pid=-123456789,-223456789,-323456789 in die die Command-Option zu schreiben. Bei mir macht das folgendes Skript:

        setState("javascript.0.heos.192_168_XXX_XXX.command", 'set_group?pid=-123456789,-223456789,-323456789');
        

        Für -123456789 etc natürlich jeweils die PID des Lautsprechers angeben. 😉 ACHTUNG: immer mit einem eventuellen MINUS DAVOR.

        <size size="85">„Alte Knaben haben genauso ihr Spielzeug wie die jungen, der Unterschied liegt lediglich im Preis.“

        Benjamin Franklin</size>

        1 Antwort Letzte Antwort
        0
        • P Offline
          P Offline
          Postmymind
          schrieb am zuletzt editiert von
          #15

          Funktioniert! Danke! So kann ich meine Etagen-Gruppensteuerung realisieren.

          1 Antwort Letzte Antwort
          0
          • S Offline
            S Offline
            sashe
            schrieb am zuletzt editiert von
            #16

            Hey,

            das Script funktioniert echt Prima. Allerdings kriege ich keine Presets? Jemand ne Idee? Und ja, die Logindaten stimmen 😄

            ! javascript.0 2018-12-09 14:27:30.435 error script.js.Automatisierungen.heos: [Heos] parseResponse: Unexpected token R in JSON at position 1 javascript.0 2018-12-09 14:27:30.434 error script.js.Automatisierungen.heos: [Heos] parseResponse: Unexpected end of JSON input javascript.0 2018-12-09 14:27:30.176 info script.js.Automatisierungen.heos: [Heos] command: load_presets !

            Ich kann mit play_preset&preset=1 auch meine Favoriten abspielen, habe sie allerdings nicht in den Objekten in iobroker.

            1 Antwort Letzte Antwort
            0
            • S Offline
              S Offline
              spielberger32
              schrieb am zuletzt editiert von
              #17

              Nach meinem letzten Stand geht es leider auch nur so … also über den Befehl per Skript

              <size size="85">„Alte Knaben haben genauso ihr Spielzeug wie die jungen, der Unterschied liegt lediglich im Preis.“

              Benjamin Franklin</size>

              1 Antwort Letzte Antwort
              0
              • S Offline
                S Offline
                sashe
                schrieb am zuletzt editiert von
                #18

                Naja, wenn ich mir den Quelltext seines Favoriten-Widgets angucke, hat er die Presets als Objekte..

                "javascript.1.heos.presets.4.image_url"

                Das habe ich nicht

                1 Antwort Letzte Antwort
                0
                • UhulaU Offline
                  UhulaU Offline
                  Uhula
                  schrieb am zuletzt editiert von
                  #19

                  Nach dem Scriptstart wird ein Connect zum Heos System aufgebaut, connected sich mindestens ein Player, wird in Zeil 301

                  this.getMusicSources();

                  aufgerufen, was zum Auslesen der Presets führen sollte. Erhält das Script vom Heos-Player eine Antwort, dann werden die Presets als Objekte im Script ab Zeile 430 erzeugt. Meine Vermutung ist, dass die Antwort des Heos-Players nicht so aussieht, wie im Script erwartet, Bsp ab Zeile 419.

                  Dieses Laden der Presets kann man auch später, nach Scriptstart, manuell aufrufen: heos.getMusicSources();

                  Bsp:

                  // Heos Instanz erzeugen und verbinden   
                  var heos = new Heos( );
                  heos.connect();
                  
                  ...
                  
                  heos.getMusicSources();
                  
                  

                  Noch ein Hinweis. Ich habe meine ioBroker Installation vom Pi3 auf einen Windows10 Rechner umziehen lassen. Da hier der node-ssdp Client wohl anders arbeitet, musste ich im Script beim connect() (ab Zeile 224) die Zeile "this.nodessdp_client.explicitSocketBind = true; " ergänzen:

                  connect() { 
                      try {
                          this.log('connecting to HEOS ...');
                          setState( this.statePath+"connected", false );
                          const NodeSSDP = require('node-ssdp').Client;
                  	    this.nodessdp_client = new NodeSSDP();
                  	    this.nodessdp_client.explicitSocketBind = true;  // <--- notwendig für Windows10 !
                              ...    
                  } 
                  

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

                  1 Antwort Letzte Antwort
                  0
                  • S Offline
                    S Offline
                    sashe
                    schrieb am zuletzt editiert von
                    #20

                    Danke. Mal schauen ob ich das fixen kann. Wenn nicht hardcode ich die Favoriten halt darein. Ansteuern kann ich sie ja und eigentlich ändern wir die auch nicht.

                    1 Antwort Letzte Antwort
                    0
                    • B Offline
                      B Offline
                      Brati
                      schrieb am zuletzt editiert von
                      #21

                      Bei mir funktioniert der HEOS Login momentan auf keinem Gerät (AVR, HS1 Box, App, ioBroker…). Vielleicht ist auch gerade der Wurm drin. Am WE lief es noch.

                      Grüße

                      Brati

                      CCU2 - 46 Geräte, ioBroker auf Intel NUC (DN2820FYKH) mit Tab als Frontend, Projekt Gartenhaus mit HM

                      1 Antwort Letzte Antwort
                      0
                      • B Offline
                        B Offline
                        Brati
                        schrieb am zuletzt editiert von
                        #22

                        @Brati:

                        Bei mir funktioniert der HEOS Login momentan auf keinem Gerät (AVR, HS1 Box, App, ioBroker…). Vielleicht ist auch gerade der Wurm drin. Am WE lief es noch.

                        Grüße

                        Brati `

                        Heute läuft wieder alles, werden jetzt vielleicht die Presets geladen?

                        CCU2 - 46 Geräte, ioBroker auf Intel NUC (DN2820FYKH) mit Tab als Frontend, Projekt Gartenhaus mit HM

                        1 Antwort Letzte Antwort
                        0
                        • B Offline
                          B Offline
                          bassface
                          schrieb am zuletzt editiert von
                          #23

                          Moin,

                          der HEOS Login funktioniert bei mir.

                          Die Objekte für die Favoriten werden auch erstellt.

                          Allerdings erhalte ich weiterhin einen Fehler. Kann ich die abstellen bzw. beheben?

                          ! ````
                          17:40:07.068 error javascript.0 script.js.Haushalt.Wohnzimmer.Denon.HEOS_bySkript: [Heos] parseResponse: Unexpected end of JSON input
                          17:40:07.069 error javascript.0 script.js.Haushalt.Wohnzimmer.Denon.HEOS_bySkript: [Heos] parseResponse: Unexpected string in JSON at position 1t

                          
                          Beste Grüße
                          1 Antwort Letzte Antwort
                          0
                          • B Offline
                            B Offline
                            Brati
                            schrieb am zuletzt editiert von
                            #24

                            @bassface:

                            Moin,

                            der HEOS Login funktioniert bei mir.

                            Die Objekte für die Favoriten werden auch erstellt.

                            Allerdings erhalte ich weiterhin einen Fehler. Kann ich die abstellen bzw. beheben?

                            ! ````
                            17:40:07.068 error javascript.0 script.js.Haushalt.Wohnzimmer.Denon.HEOS_bySkript: [Heos] parseResponse: Unexpected end of JSON input
                            17:40:07.069 error javascript.0 script.js.Haushalt.Wohnzimmer.Denon.HEOS_bySkript: [Heos] parseResponse: Unexpected string in JSON at position 1t

                            
                            Beste Grüße `  
                            

                            Du könntest mal versuchen die Objekte (IP Adressen und darunter) zu löschen und dann das Script neu starten. War der Fehler von Anfang an da?

                            Grüße

                            Brati

                            CCU2 - 46 Geräte, ioBroker auf Intel NUC (DN2820FYKH) mit Tab als Frontend, Projekt Gartenhaus mit HM

                            1 Antwort Letzte Antwort
                            0
                            • B Offline
                              B Offline
                              bassface
                              schrieb am zuletzt editiert von
                              #25

                              Hey,

                              danke für die Rückmeldung.

                              Die Meldung kommt seit dem ersten Start des Skripts.

                              Die Objekte hatte ich bereits einmal gelöscht, die Meldungen kommen dann aber erneut sofern das Skript gestartet wird.

                              Die Funktionen des Skripts werden allerdings nicht beinträchtigt und da die Meldung nur bei Skriptstart kommt kann ich damit leben.

                              Ist ja nicht so häufig.

                              Daher auch noch herzlichen an Uhula für deine Arbeit. Für meine Bedürfnisse perfekt!

                              Gruß

                              1 Antwort Letzte Antwort
                              0
                              • C Offline
                                C Offline
                                charon
                                schrieb am zuletzt editiert von
                                #26

                                @Uhula : Könntest Du das das initiale Posting mit dem Script und den Widgets bitte nochmal anschauen und ggfs. überarbeiten? Es scheint, als würde die neue Forensoftware deinen Text verhunzen. Habe schon versucht per "Quote" an den Plaintext zu kommen, aber das war nicht von Erfolg gekrönt.

                                Falls es nicht geht wäre ja vielleicht auch pastebin oder dein github-Repo eine Möglichkeit?

                                Vielen Dank im Voraus und viele Grüße

                                B 1 Antwort Letzte Antwort
                                0
                                • C charon

                                  @Uhula : Könntest Du das das initiale Posting mit dem Script und den Widgets bitte nochmal anschauen und ggfs. überarbeiten? Es scheint, als würde die neue Forensoftware deinen Text verhunzen. Habe schon versucht per "Quote" an den Plaintext zu kommen, aber das war nicht von Erfolg gekrönt.

                                  Falls es nicht geht wäre ja vielleicht auch pastebin oder dein github-Repo eine Möglichkeit?

                                  Vielen Dank im Voraus und viele Grüße

                                  B Offline
                                  B Offline
                                  Brati
                                  schrieb am zuletzt editiert von
                                  #27

                                  @charon sagte in [Vorlage] Denon HEOS Script:

                                  @Uhula : Könntest Du das das initiale Posting mit dem Script und den Widgets bitte nochmal anschauen und ggfs. überarbeiten? Es scheint, als würde die neue Forensoftware deinen Text verhunzen. Habe schon versucht per "Quote" an den Plaintext zu kommen, aber das war nicht von Erfolg gekrönt.

                                  Falls es nicht geht wäre ja vielleicht auch pastebin oder dein github-Repo eine Möglichkeit?

                                  Vielen Dank im Voraus und viele Grüße

                                  Das Script sieht tatsächlich komisch aus :). Hier nochmal:

                                  /****************************
                                   * HEOS Script for ioBroker
                                   ****************************
                                   *  23.01.2018 Uhula, MIT License, no warranty, use on your own risc
                                   * 
                                   * Wichtig!
                                   ****************************
                                   * (a) Im Javascript-Adapter muss in der Instanz-Konfiguration "node-ssdp" mit angegeben werden!
                                   * (b) Wenn mit Favoriten (Presets) gearbeitet werden soll, müssen die HEOS-Konto Logindaten in
                                   *     den beiden Konstanten HEOS_USERNAME (EmailAdr) und HEOS_PASSWORD hier im Script in der 
                                   *     Konfiguration angegeben werden (so, wie in der HEOS App)!
                                   * (c) Eine Konfiguration von IP-Adressen und Player-IDs ist nicht notwendig!
                                   * (d) U.U. kann es notwendig sein das Script nach dem 1.Start zu beenden und nach 30 Sek erneut zu starten, da
                                   *     die Neuanlage der ioBroker States etwas Zeit benötigt. Warnungen sind dabei zu ignorieren. ;-)
                                   *
                                   * 
                                   * Funktion
                                   ****************************
                                   * Das Script stellt zwei JS Klassen zur Steuerung der Denon HEOS Geräte zur Verfügung. Die
                                   * class Heos dient dabei dem Erkennen und Steuern der HEOS Geräte. Die class HeosPlayer dient der 
                                   * Interpretation der Antworten der Heos Geräte.
                                   * 
                                   * Das Script muss lediglich gestartet werden, es sucht dann im Netzwerk nach HEOS Playern und
                                   * erzeugt in der aktuellen Javascript-Instanz einen Subeintrag für die Favoriten und je einen Subeintrag
                                   * für jeden gefundenen Player. Dort wiederum werden State-Variablen zur Aufnahme der Player-Daten angelegt.
                                   * 
                                   * Das Script erzeugt auch on-Handler um auf Steuerungen über vis und andere Scripte an den State-Variablen
                                   * reagieren zu können.
                                   * 
                                   * Beim Beenden des Scripts werden alle Verbindungen und on-Handler geschlossen.
                                   * 
                                   * Das Script ermöglicht die HEOS Player zu steuern, es soll aber nicht die HEOS App ersetzen. Dazu fehlen
                                   * etliche Funktionen wie Playlisten-Handhabung, Gruppensteuerung usw.
                                   * 
                                   * 
                                   * class Heos
                                   ****************************
                                   * (a) Erkennen von HEOS Geräten (Playern)
                                   *     Das Erkennen der HEOS Geräte findet via UPD unter Nutzung von node-ssdp statt. node-ssdp muss dazu im 
                                   *     Javascript-Adapter in der Konfiguration mit angegeben werden!
                                   * (b) der Kommunikation über TelNet 
                                   *     Es wird genau eine TelNet Verbindung zu einem HEOS Gerät aufgebaut, dieses reicht die Sendungen
                                   *     und Antworten zentral weiter
                                   * (c) der Ermittlung von Favoriten (Presets) und 
                                   *     Für jeden Favorit wird ein ioBroker State heos.presets.n mit entsprechenden Sub-States erzeugt.
                                   *     Zur Nutzung der Presets ist ein SignIn notwendig, hierzu müssen HEOS_USERNAME und HEOS_PASSWORD
                                   *     gesetzt werden.
                                   * (d) dem Instanziieren der class HeosPlayer je HEOS Gerät. 
                                   *     Je HEOS Gerät wird ein ioBroker-State mit der IP-Adresse des Players erzeugt, dieser State erhält
                                   *     diverse Sub-States
                                   * 
                                   * State-Variable
                                   * --------------
                                   * .heos.command (write)
                                   *   Hierüber können der Heos-Klasse Befehle übergeben werden:
                                   *   connect      : Verbindung zu HEOS aufbauen bzw. erneut aufbauen (praktisch ein reset)
                                   *   disconnect   : Verbindung zu HEOS beenden
                                   *   load_presets : lädt die Favoriten neu
                                   * 
                                   * Favoriten (je Favorit ein Unterordner n=1 bis Anzahl)
                                   * 
                                   * .heos.presets.<n>.image_url (read)
                                   *   Bild des Favoriten 
                                   * 
                                   * .heos.presets.<n>.name (read)
                                   *   Name des Favoriten
                                   * 
                                   * .heos.presets.<n>.playable (read)
                                   *   Spielbar? true/false
                                   * 
                                   * .heos.presets.<n>.type (read)
                                   *   Typ des Favoriten (station, ...)
                                   *    
                                   *  
                                   * class HeosPlayer 
                                   ****************************
                                   * (a) der Steuerung genau eines HEOS Gerätes. Hierzu wird die zentrale Telnet Verbindung der class Heos genutzt.
                                   * (b) dem Erzeugen der ioBroker-States zum Speichern der Geräte-Werte
                                   * (b) der Auswertung von Antworten der HEOS Geräte und Zuweisung an die entsprechenden ioBroker-States
                                   * 
                                   * State-Variable
                                   * --------------
                                   * .heos.<player_ip>.command (write)
                                   *   Hierüber können dem Heos-Player Befehle übergeben werden. Diese werden im Klartext in die State-Variable
                                   *   geschrieben. Getrennt durch das | Zeichen können mehrere Befehle hintereinander eingetragen werden.
                                   *   Bsp: Setzen der Lautstärke auf 20 und Abspielen des 1.Favoriten
                                   *        set_volume&level=20|play_preset&preset=1
                                   * 
                                   *   set_volume&level=0|1|..|100          : Setzt die gewünschte Lautstärke 
                                   *   set_play_state&state=play|pause|stop : Startet und stoppt die Wiedergabe
                                   *   set_play_mode&repeat=on_all|on_one|off&shuffle=on|off: Setzt Wiederholung und Zufallsweidergabe
                                   *   set_mute&state=on|off                : Stumm schalten oder nicht
                                   *   volume_down&step=1..10               : Lautstärke verringern um   
                                   *   volume_up&step=1..10                 : Lauststäre erhöhen um
                                   *   play_next                            : Nächsten Titel spielen
                                   *   play_previous                        : Vorherigen Titel spielen
                                   *   play_preset&preset=1|2|..|n          : Favorit Nr n abspielen
                                   *   play_stream&url=url_path             : URL-Stream abspielen
                                   * 
                                   *   Befehle, die intern genutzt werden und nicht aufgerufen werden müssen:
                                   *
                                   *   get_volume              : Füllt den .heos.<player_ip>.volume State
                                   *   get_play_state          : Füllt den .heos.<player_ip>.play_state State
                                   *   get_play_mode           : Füllt den .heos.<player_ip>.play_mode State 
                                   *   get_now_playing_media   : Füllt die .heos.<player_ip>.now_playing_media_... States
                                   *
                                   *
                                   * .heos.<player_ip>.cur_pos (read)
                                   *   lfd. Position der Wiedergabe in [Sek]
                                   * 
                                   * .heos.<player_ip>.cur_pos_MMSS (read)
                                   *   lfd. Position der Wiedergabe im Format MM:SS
                                   * 
                                   * .heos.<player_ip>.duration (read)
                                   *   Länge des aktuellen Titels in [Sek]
                                   * 
                                   * .heos.<player_ip>.duration_MMSS (read)
                                   *   Länge des aktuellen Titels im Format MM:SS
                                   * 
                                   * .heos.<player_ip>.ip (read)
                                   *   IP-Adresse des HEOS Players
                                   * 
                                   * .heos.<player_ip>.last_error (read)
                                   *   Text des letzten Fehlers, der vom Player gesendet wurde. Wird bei jedem neuen Befehl zurückgesetzt. 
                                   *   Wenn man bspw. versucht eine Wiedergabe über Amazon o.ä. zu starten und es gibt aber keine Verbindung
                                   *   dahin, steht hier der Fehlertext drin
                                   * 
                                   * .heos.<player_ip>.model (read)
                                   *   Modell des HEOS Players
                                   * 
                                   * .heos.<player_ip>.mute (read write)
                                   *   Boolsche Variable, die anzeigt ob der Player gemutet (Stumm geschaltet) wurde. Hierüber kann auch ein 
                                   *   mute gesetzt werden
                                   * 
                                   * .heos.<player_ip>.name (read)
                                   *   Name des HEOS Players
                                   * 
                                   * .heos.<player_ip>.now_playing_media_... (read)
                                   *   Eine Gruppe von States, in welchen Infos über den aktuellen Titel gespeichert werden, wird automatisch
                                   *   aktualisiert. 
                                   * 
                                   * .heos.<player_ip>.pid (read)
                                   *   Player-ID des HEOS Players
                                   * 
                                   * .heos.<player_ip>.play_mode_repeat (read write)
                                   *   Repeat-Modus der Wiedergabe. Mögliche Werte: on_all|on_one|off  
                                   * 
                                   * .heos.<player_ip>.play_mode_shuffle (read write)
                                   *   Zufallswiedergabe true/false
                                   * 
                                   * .heos.<player_ip>.play_state (read write)
                                   *   Zustand des Players. Mögliche Werte play|pause|stop
                                   * 
                                   * .heos.<player_ip>.serial (read)
                                   *   Seriennummmer des HEOS Players
                                   * 
                                   * .heos.<player_ip>.volume (read write)
                                   *   Lautstärke im Bereich 0 - 100. 
                                   * 
                                   * 
                                   * 
                                   * Weiterführende Links
                                   ****************************
                                   * HEOS CLI Protokoll: http://rn.dmglobal.com/euheos/HEOS_CLI_ProtocolSpecification.pdf
                                   * http://forum.iobroker.net/viewtopic.php?f=30&t=5693&p=115554#p115554
                                   * 
                                   **/
                                  
                                  /****************************
                                   * Konfiguration
                                   ****************************/
                                   
                                  const HEOS_USERNAME = 'xxxx.';
                                  const HEOS_PASSWORD = 'xxx';
                                  const DEBUG = false;
                                  
                                  
                                  /****************************
                                   * ab hier nichts mehr ändern ;-) 
                                   ****************************/
                                  
                                  var net = require('net');
                                  
                                  const stateDISCONNECTED = 0;
                                  const stateCONNECTING = 1;
                                  const stateCONNECTED = 2;
                                  
                                  /********************
                                   * class Heos
                                   ********************/
                                  class Heos  {
                                  
                                  constructor() {
                                      this.init();
                                  
                                      createState( this.statePath+'command', '', {name: 'Kommando für Heos-Script' });
                                      createState( this.statePath+'connected', false, {name: 'Verbunden?' });
                                      on({id: this.statePath+'command', change: "any"}, (obj) => {
                                              this.executeCommand( obj.state.val );
                                          });
                                  }
                                  
                                  logDebug(msg) { if (DEBUG) console.log('[Heos] '+msg); }
                                  log(msg) { console.log('[Heos] '+msg); }
                                  logWarn(msg) { console.warn('[Heos] '+msg); }
                                  logError(msg) { console.error('[Heos] '+msg); }
                                  
                                  
                                  init() {
                                      this.statePath = 'javascript.'+instance+'.heos.';
                                      this.players = [];
                                      this.net_client = undefined;
                                      this.nodessdp_client = undefined;
                                  
                                      this.ip='';
                                      this.msgs = [];
                                      this.lastResponse = '';
                                      this.state = stateDISCONNECTED;
                                  }
                                  
                                  connect() { try {
                                      setState( this.statePath+"connected", false );
                                      const NodeSSDP = require('node-ssdp').Client;
                                     this.nodessdp_client = new NodeSSDP();
                                     this.nodessdp_client.on('response', (headers, statusCode, rinfo) => this.onNodeSSDPResponse(rinfo) );
                                     this.nodessdp_client.on('error', error => {   client.close(); this.logError(error); });
                                     const searchTargetName = 'urn:schemas-denon-com:device:ACT-Denon:1';
                                     this.nodessdp_client.search(searchTargetName);
                                  } catch(err) { this.logError( 'onResponse: '+err.message ); } }
                                  
                                  
                                  /** Alle Player stoppen und die TelNet Verbindung schließen 
                                   **/
                                  disconnect() {
                                      this.log('disconnecting from HEOS ...');
                                      unsubscribe('javascript.1.heos');
                                  
                                      if (typeof this.net_client!=='undefined') {
                                          this.registerChangeEvents( false );
                                          
                                          this.net_client.destroy();
                                          this.net_client.unref();
                                      }
                                      setState( this.statePath+"connected", false );
                                      this.log('disconnected from HEOS');
                                  }
                                  
                                  executeCommand(cmd) {
                                      this.log('command: '+cmd);
                                      switch (cmd) {
                                          case 'load_presets' :
                                              this.getMusicSources();
                                              break;
                                          case 'connect' :
                                              this.disconnect();
                                              this.init();
                                              this.connect();
                                              break;
                                          case 'disconnect' :
                                              this.disconnect();
                                              break;
                                      }
                                  }
                                  /** es wurde mindestens ein Player erkannt, nun über dessen IP alle bekannten HEOS Player
                                   *  durch senden von "player/get_players" ermitteln
                                   */
                                  onNodeSSDPResponse(rinfo) { try {
                                      // rinfo {"address":"192.168.2.225","family":"IPv4","port":53871,"size":430}
                                      if (typeof this.net_client=='undefined') {
                                          this.ip = rinfo.address;
                                          this.log('connecting to '+this.ip+' ...');
                                          this.net_client = net.connect({host:this.ip, port:1255});
                                          this.net_client.setKeepAlive(true, 5000);
                                  
                                          this.state = stateCONNECTING;
                                  
                                          this.net_client.on('error',(error) => {
                                              this.logError(error);
                                              this.disconnect();
                                          }); 
                                      
                                          this.net_client.on('connect',  () => {
                                              setState( this.statePath+"connected", true );
                                              this.state = stateCONNECTED;
                                              this.log('connected to '+this.ip);
                                              this.getPlayers();
                                              this.registerChangeEvents( true );
                                              this.signIn();
                                              this.getMusicSources();
                                          });
                                          
                                          // Gegenseite hat die Verbindung geschlossen 
                                          this.net_client.on('end',  () => {              
                                              this.logWarn('HEOS closed the connection to '+this.ip);
                                              this.disconnect();
                                          });
                                  
                                          // timeout
                                          this.net_client.on('timeout',  () => {              
                                              this.logWarn('Timeout trying connect to '+this.ip);
                                              this.disconnect();
                                          });
                                      
                                          // Datenempfang
                                          this.net_client.on('data', (data) => this.onData(data)  );
                                      }
                                  } catch(err) { this.logError( 'onNodeSSDPResponse: '+err.message ); } }
                                  
                                  
                                  
                                  /** es liegen Antwort(en) vor
                                   **/
                                  onData(data) {  try {
                                      data = data.toString();
                                      data=data.replace(/[\n\r]/g, '');    // Steuerzeichen "CR" entfernen   
                                      // es können auch mehrere Antworten vorhanden sein! {"heos": ... } {"heos": ... }
                                      // diese nun in einzelne Antworten zerlegen
                                      data=data.replace(/{"heos":/g, '|{"heos":');    
                                      var responses = data.split('|');
                                      responses.shift();
                                      for (var r=0; r<responses.length; r++ ) {
                                          this.parseResponse(responses[r]);
                                      }
                                      // wenn weitere Msg zum Senden vorhanden sind, die nächste senden
                                      if (this.msgs.length>0)
                                          this.sendNextMsg();
                                  } catch(err) { this.logError( 'onData: '+err.message ); } }
                                  
                                  /** Antwort(en) verarbeiten. Sich wiederholende Antworten ignorieren
                                   **/
                                  parseResponse (response) { try {
                                      if (response == this.lastResponse )
                                          return
                                      this.lastResponse = response;        
                                      
                                      var jmsg;
                                      var i;
                                      var jdata = JSON.parse(response);
                                      if ( !jdata.hasOwnProperty('heos') || !jdata.heos.hasOwnProperty('command') || !jdata.heos.hasOwnProperty('message') ) 
                                          return;
                                  
                                      // msg auswerten
                                      try {
                                          jmsg = '{"' + decodeURI(jdata.heos.message).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"').replace(/\s/g,'_') + '"}';
                                          jmsg = JSON.parse(jmsg);
                                      } catch(err) {
                                          jmsg = {};
                                      }
                                  
                                      this.logDebug('parseResponse: '+response); 
                                  
                                      // result ?
                                      var result = 'success';
                                      if (jdata.heos.hasOwnProperty('result') ) result = jdata.heos.result;
                                      if ( result!='success' ) { 
                                          setState(this.statePath+'last_error', jmsg.text);
                                          this.logWarn(jmsg.text);
                                      }
                                  
                                      // cmd auswerten
                                      var cmd = jdata.heos.command.split('/');
                                      var cmd_group = cmd[0];
                                      cmd = cmd[1];
                                  
                                      switch (cmd_group) {
                                          case 'player':
                                              switch (cmd) {
                                                      // {"heos": {"command": "player/get_players", "result": "success", "message": ""}, 
                                                      //  "payload": [{"name": "HEOS Bar", "pid": 1262037998, "model": "HEOS Bar", "version": "1.430.160", "ip": "192.168.2.225", "network": "wifi", "lineout": 0, "serial": "ADAG9170202780"}, 
                                                      //              {"name": "HEOS 1 rechts", "pid": -1746612370, "model": "HEOS 1", "version": "1.430.160", "ip": "192.168.2.201", "network": "wifi", "lineout": 0, "serial": "AMWG9170934429"}, 
                                                      //              {"name": "HEOS 1 links", "pid": 68572158, "model": "HEOS 1", "version": "1.430.160", "ip": "192.168.2.219", "network": "wifi", "lineout": 0, "serial": "AMWG9170934433"}
                                                      //             ]}
                                                  case 'get_players' :
                                                      if ( (jdata.hasOwnProperty('payload')) && (this.players.length===0) ) {
                                                          for (i=0; i<jdata.payload.length; i++) {
                                                              var player = jdata.payload[i];
                                                              this.players.push(player);
                                                          }
                                                          this.startPlayers();
                                                      }
                                                      break;
                                              }
                                              break;
                                  
                                          // {"heos": {"command": "browse/get_music_sources", "result": "success", "message": ""}, 
                                          //  "payload": [{"name": "Amazon", "image_url": "https://production...png", "type": "music_service", "sid": 13}, 
                                          //              {"name": "TuneIn", "image_url": "https://production...png", "type": "music_service", "sid": 3}, 
                                          //              {"name": "Local Music", "image_url": "https://production...png", "type": "heos_server", "sid": 1024}, 
                                          //              {"name": "Playlists", "image_url": "https://production...png", "type": "heos_service", "sid": 1025}, 
                                          //              {"name": "History", "image_url": "https://production...png", "type": "heos_service", "sid": 1026}, 
                                          //              {"name": "AUX Input", "image_url": "https://production...png", "type": "heos_service", "sid": 1027}, 
                                          //              {"name": "Favorites", "image_url": "https://production...png", "type": "heos_service", "sid": 1028}]}
                                          case 'browse':
                                              switch (cmd) {
                                                  case 'get_music_sources' :
                                                      if ( (jdata.hasOwnProperty('payload')) ) {
                                                          for (i=0; i<jdata.payload.length; i++) {
                                                              var source = jdata.payload[i];
                                                              if (source.name=='Favorites') {
                                                                  this.browse(source.sid);
                                                              }
                                                          }
                                                      }
                                  
                                                      break;
                                                      
                                         // {"heos": {"command": "browse/browse", "result": "success", "message": "pid=1262037998&sid=1028&returned=5&count=5"}, 
                                         //  "payload": [{"container": "no", "mid": "s17492", "type": "station", "playable": "yes", "name": "NDR 2 (Adult Contemporary Music)", "image_url": "http://cdn-radiotime-logos.tunein.com/s17492q.png"}, 
                                         //              {"container": "no", "mid": "s158432", "type": "station", "playable": "yes", "name": "Absolut relax (Easy Listening Music)", "image_url": "http://cdn-radiotime-logos.tunein.com/s158432q.png"}, 
                                         //              {"container": "no", "mid": "catalog/stations/A1W7U8U71CGE50/#chunk", "type": "station", "playable": "yes", "name": "Ed Sheeran", "image_url": "https://images-na.ssl-images-amazon.com/images/G/01/Gotham/DE_artist/EdSheeran._SX200_SY200_.jpg"}, 
                                         //              {"container": "no", "mid": "catalog/stations/A1O1J39JGVQ9U1/#chunk", "type": "station", "playable": "yes", "name": "Passenger", "image_url": "https://images-na.ssl-images-amazon.com/images/I/71DsYkU4QaL._SY500_CR150,0,488,488_SX200_SY200_.jpg"}, 
                                         //              {"container": "no", "mid": "catalog/stations/A316JYMKQTS45I/#chunk", "type": "station", "playable": "yes", "name": "Johannes Oerding", "image_url": "https://images-na.ssl-images-amazon.com/images/G/01/Gotham/DE_artist/JohannesOerding._SX200_SY200_.jpg"}], 
                                         //  "options": [{"browse": [{"id": 20, "name": "Remove from HEOS Favorites"}]}]}                    
                                                  case 'browse' :
                                                      if ( (jdata.hasOwnProperty('payload')) ) {
                                                          for (i=0; i<jdata.payload.length; i++) {
                                                              var preset = jdata.payload[i];
                                                              createState( this.statePath+'presets.'+(i+1)+'.name', preset.name, {name: 'Favoritenname ' });
                                                              createState( this.statePath+'presets.'+(i+1)+'.playable', (preset.playable=='yes'?true:false), {name: 'Favorit ist spielbar' });
                                                              createState( this.statePath+'presets.'+(i+1)+'.type', preset.type, {name: 'Favorittyp' });
                                                              createState( this.statePath+'presets.'+(i+1)+'.image_url', preset.image_url, {name: 'Favoritbild' });
                                                          }
                                                      }
                                                      break;
                                              }     
                                              break;
                                  
                                          case 'system':
                                              switch (cmd) {
                                                  case 'sign_in' :
                                                      this.log('signed in: '+jdata.heos.result);
                                                      break;
                                              }     
                                              break;
                                      }
                                  
                                  
                                      // an die zugehörigen Player weiterleiten
                                      if ( jmsg.hasOwnProperty('pid') ) {
                                          for (i=0; i<this.players.length; i++)
                                              if (jmsg.pid==this.players[i].heosPlayer.pid) {
                                                  this.players[i].heosPlayer.parseResponse (jdata, jmsg, cmd_group, cmd);
                                                  break;
                                              }
                                      }
                                  
                                      
                                  } catch(err) { this.logError( 'parseResponse: '+err.message ); } }
                                  
                                  
                                  /** sucht die zur ip passenden player-Insanz
                                   **/
                                  sendCommandToPlayer(objID, cmd ) {
                                     var ip = objID;
                                     ip = ip.split('.');
                                     var ip_ = ip[3];
                                     ip = ip_.replace(/_/g,'.');
                                     for (var p=0; p<this.players.length; p++ ) 
                                         if (this.players[p].ip == ip ) {
                                             this.players[p].heosPlayer.sendCommand( cmd );
                                             break;
                                         }
                                         
                                  } 
                                  
                                  /** Für die gefundenen HEOS Plyer entsprechende class HeosPlayer Instanzen bilden 
                                   **/
                                  startPlayers() { try {
                                      var i=0;
                                      for (i=0; i<this.players.length; i++) {
                                         this.players[i].heosPlayer = new HeosPlayer( this, this.players[i]  );
                                      }
                                      // Events setzen
                                      for (i=0; i<this.players.length; i++) {
                                          var statePath = this.players[i].heosPlayer.statePath;
                                          // on-Event für command
                                          on({id: statePath+'command', change: "any"}, (obj) => {
                                              this.sendCommandToPlayer( obj.id, obj.state.val );
                                          });
                                  
                                          // on-Event für volume (nur wenn ack=false, also über vis)
                                          on({id: statePath+'volume', change:'ne', ack:false }, (obj) => {
                                              this.sendCommandToPlayer( obj.id, 'set_volume&level='+obj.state.val );
                                          });
                                          // on-Event für mute (nur wenn ack=false, also über vis)
                                          on({id: statePath+'mute', change: 'ne', ack:false}, (obj) => {
                                              this.sendCommandToPlayer( obj.id, 'set_mute&state='+ (obj.state.val === true ? 'on' : 'off') );
                                          });
                                          // on-Event für play_mode_shuffle (nur wenn ack=false, also über vis)
                                          on({id: statePath+'play_mode_shuffle', change: 'ne', ack:false}, (obj) => {
                                              this.sendCommandToPlayer( obj.id, 'set_play_mode&shuffle='+ (obj.state.val === true ? 'on' : 'off') );
                                          });
                                          // on-Event für play_state (nur wenn ack=false, also über vis)
                                          on({id: statePath+'play_state', change: 'ne', ack:false}, (obj) => {
                                              this.sendCommandToPlayer( obj.id, 'set_play_state&state='+ obj.state.val );
                                          });
                                      }    
                                  } catch(err) { this.logError( 'startPlayers: '+err.message ); } }
                                  
                                  
                                  
                                  getPlayers() {
                                      if (this.state == stateCONNECTED) {
                                          this.msgs.push( 'heos://player/get_players\n' );
                                          this.sendNextMsg();
                                      }
                                  }
                                  
                                  registerChangeEvents( b ) {
                                      if (this.state == stateCONNECTED) {
                                          if (b) this.msgs.push( 'heos://system/register_for_change_events?enable=on' );
                                          else this.msgs.push( 'heos://system/register_for_change_events?enable=off' );
                                          this.sendNextMsg();
                                      }
                                  }
                                  
                                  signIn() {
                                      if (this.state == stateCONNECTED) {
                                          // heos://system/sign_in?un=heos_username&pw=heos_password
                                          this.msgs.push( 'heos://system/sign_in?un='+HEOS_USERNAME+'&pw='+HEOS_PASSWORD );
                                          this.sendNextMsg();
                                      }
                                  }
                                  
                                  getMusicSources() {
                                      if (this.state == stateCONNECTED) {
                                          // heos://browse/get_music_sources
                                          this.msgs.push( 'heos://browse/get_music_sources' );
                                          this.sendNextMsg();
                                      }
                                      
                                  }
                                  
                                  browse(sid) {
                                      if (this.state == stateCONNECTED) {
                                          // heos://browse/browse?sid=source_id
                                          this.msgs.push( 'heos://browse/browse?sid='+sid );
                                          this.sendNextMsg();
                                      }
                                      
                                  }
                                  
                                  
                                  sendNextMsg () {
                                      if (this.msgs.length>0) {
                                          var msg = this.msgs.shift();
                                          this.sendMsg(msg);
                                      }
                                  }
                                  
                                  // Nachricht an player senden
                                  sendMsg (msg) {
                                      this.net_client.write(msg + "\n");
                                      this.logDebug("data sent: "+ msg);
                                  }
                                  
                                  
                                  } // end of class Heos
                                  
                                  /********************
                                   * class HeosPlayer
                                   ********************/
                                  
                                  class HeosPlayer  {
                                  
                                  constructor(heos, player) {
                                      this.heos = heos;
                                      this.ip = player.ip;
                                      this.name = player.name;
                                      this.pid = player.pid;
                                      this.model = player.model;
                                      this.serial = player.serial;
                                  
                                      this.statePath = 'javascript.'+instance+'.heos.'+this.ip.replace(/\./g,'_')+".";
                                  
                                      this.log('starting HEOS player for IP '+this.ip);
                                  
                                      this.createStates();
                                  
                                      // Initialiserung der States nach 5 Sek
                                      setTimeout(() => {
                                          this.setState('ip',this.ip);
                                          this.setState('name',this.name);
                                          this.setState('pid',this.pid);
                                          this.setState('model',this.model);
                                          this.setState('serial',this.serial);
                                          this.sendCommand('get_play_state|get_play_mode|get_now_playing_media|get_volume');
                                          
                                      }, 5000 );
                                  
                                  }
                                  
                                  static version () { return "0.1"; }
                                  
                                  logDebug(msg) { if (DEBUG) console.log('[HeosPlayer '+this.ip+'] '+msg); }
                                  log(msg) { console.log('[HeosPlayer '+this.ip+'] '+msg); }
                                  logWarn(msg) { console.warn('[HeosPlayer '+this.ip+'] '+msg); }
                                  logError(msg) { console.error('[HeosPlayer '+this.ip+'] '+msg); }
                                  
                                  
                                  /** Anlage der ioBroker States für den Player
                                   **/
                                  createStates() {
                                      const states = [
                                          { id:"command",                     name:"Kommando für HEOS Aufrufe"},
                                          { id:"ip",                          name:"IP Adresse"},
                                          { id:"pid",                         name:"Player-ID "},
                                          { id:"name",                        name:"Name des Players"},
                                          { id:"model",                       name:"Modell des Players"},
                                          { id:"serial",                      name:"Seriennummer des Players"},
                                          { id:"last_error",                  name:"Letzter Fehler"},
                                          { id:"volume",                      name:"Aktuelle Lautstärke"},
                                          { id:"mute",                        name:"Mute aktiviert?"},
                                          { id:"play_state",                  name:"Aktueller Wiedergabezustand"},
                                          { id:"play_mode_repeat",            name:"Wiedergabewiederholung"},
                                          { id:"play_mode_shuffle",           name:"Zufällige Wiedergabe"},
                                          { id:"now_playing_media_type",      name:"Aktuelle Wiedergabemedium"},
                                          { id:"now_playing_media_song",      name:"Aktuelles Lied"},
                                          { id:"now_playing_media_station",   name:"Aktuelle Station"},
                                          { id:"now_playing_media_album",     name:"Aktuelle Wiedergabemedium"},
                                          { id:"now_playing_media_artist",    name:"Aktueller Artist"},
                                          { id:"now_playing_media_image_url", name:"Aktuelles Coverbild"},
                                          { id:"now_playing_media_album_id",  name:"Aktuelle Album-ID"},
                                          { id:"now_playing_media_mid",       name:"Aktuelle mid"},
                                          { id:"now_playing_media_qid",       name:"Aktuelle qid"},
                                          { id:"cur_pos",                     name:"lfd. Position"},
                                          { id:"duration",                    name:"Dauer"},
                                          { id:"cur_pos_MMSS",                name:"lfd. Position MM:SS"},
                                          { id:"duration_MMSS",               name:"Dauer MM:SS"}
                                      ];
                                  
                                      var def = "";
                                      for (var s=0; s<states.length; s++) {
                                          var state = states[s];
                                          if (this.hasOwnProperty(state.id)) def=this[state.id]; else def='';
                                          createState( this.statePath+state.id, def, {name: state.name });
                                      }
                                      
                                  }
                                  
                                  
                                  /** wandelt einen sek Wert in MM:SS Darstellung um
                                   **/
                                  toMMSS (s) {
                                      var sec_num = parseInt(s, 10); 
                                      var minutes = Math.floor(sec_num  / 60);
                                      var seconds = sec_num - (minutes * 60);
                                      if (seconds < 10) {seconds = "0"+seconds;}
                                      return minutes+':'+seconds;
                                  }
                                  
                                  /** setState wrapper
                                   **/
                                  setState(id,val) {
                                     setState(this.statePath+id, val, true);    
                                  }
                                  
                                  /** Auswertung der empfangenen Daten
                                   **/
                                  parseResponse (jdata, jmsg, cmd_group, cmd) { try {
                                      switch (cmd_group) {
                                          case 'event':
                                              switch (cmd) {
                                                  case 'player_playback_error' :
                                                      this.setState('last_error', jmsg.error.replace(/_/g,' '));
                                                      this.logError(jmsg.error.replace(/_/g,' '));
                                                      break;
                                                  case 'player_state_changed' :
                                                      this.setState("play_state", jmsg.state);
                                                      break;
                                                  case 'player_volume_changed' :
                                                      this.setState("volume", jmsg.level );
                                                      break;
                                                  case 'player_mute_changed' :
                                                      this.setState("mute", (jmsg.state=='on' ? true : false) );
                                                      break;
                                                  case 'player_repeat_mode_changed' :
                                                      this.setState("play_mode_shuffle", jmsg.shuffle );
                                                      break;
                                                  case 'player_shuffle_mode_changed' :
                                                      this.setState("play_mode_repeat", jmsg.repeat );
                                                      break;
                                                  case 'player_now_playing_changed' :
                                                      this.sendCommand('get_now_playing_media');
                                                      break;
                                                  case 'player_now_playing_progress' :
                                                      this.setState("cur_pos", jmsg.cur_pos / 1000);
                                                      this.setState("cur_pos_MMSS", this.toMMSS(jmsg.cur_pos / 1000));
                                                      this.setState("duration", jmsg.duration / 1000);
                                                      this.setState("duration_MMSS", this.toMMSS(jmsg.duration / 1000));
                                                      break;
                                              }        
                                              break;
                                              
                                              
                                          case 'player':
                                              switch (cmd) {
                                                  case 'set_volume' :
                                                  case 'get_volume' :
                                                      if ( getState(this.statePath+"volume").val != jmsg.level)
                                                          this.setState("volume", jmsg.level);
                                                      break;
                                                  case 'set_mute' :
                                                  case 'get_mute' :
                                                      this.setState("mute", (jmsg.state=='on' ? true : false) );
                                                      break;
                                                  case 'set_play_state' :
                                                  case 'get_play_state' :
                                                      this.setState("play_state", jmsg.state);
                                                      break;
                                                  case 'set_play_mode' :
                                                  case 'get_play_mode' :
                                                      this.setState("play_mode_repeat", jmsg.repeat);
                                                      this.setState("play_mode_shuffle", (jmsg.shuffle=='on'?true:false) );
                                                      break;
                                                  case 'get_now_playing_media' :
                                                      this.setState("now_playing_media_type", jdata.payload.type);
                                                      // type == station
                                                      if (jdata.payload.type=='station') {
                                                          this.setState("now_playing_media_song", jdata.payload.song);
                                                          this.setState("now_playing_media_station", jdata.payload.station);
                                                          this.setState("now_playing_media_album", jdata.payload.album);
                                                          this.setState("now_playing_media_artist", jdata.payload.artist);
                                                          this.setState("now_playing_media_image_url", jdata.payload.image_url);
                                                          this.setState("now_playing_media_album_id", jdata.payload.album_id);
                                                          this.setState("now_playing_media_mid", jdata.payload.mid);
                                                          this.setState("now_playing_media_qid", jdata.payload.qid);
                                                          }
                                                      break;
                                              }
                                              break;
                                      } // switch
                                  
                                  
                                  } catch(err) { this.logError( 'parseResponse: '+err.message ); } }
                                   
                                  /** cmd der Form "cmd&param"  werden zur msg heos+cmd+pid+&param aufbereitet
                                      cmd der Form "cmd?param"  werden zur msg heos+cmd+?param aufbereitet
                                   **/
                                  commandToMsg (cmd) {
                                      var param = cmd.split('&');
                                      cmd = param[0];
                                      if ( param.length > 1 ) param='&'+param[1]; else param=''; 
                                      var cmd_group = 'player';
                                  
                                      switch (cmd) {
                                          case 'get_play_state':
                                          case 'get_play_mode':
                                          case 'get_now_playing_media':
                                          case 'get_volume':
                                          case 'play_next':
                                          case 'play_previous':
                                          case 'set_mute':       // &state=on|off        
                                          case 'set_volume':     // &level=1..100   
                                          case 'volume_down':    // &step=1..10   
                                          case 'volume_up':      // &step=1..10
                                          case 'set_play_state': // &state=play|pause|stop
                                          case 'set_play_mode':  // &repeat=on_all|on_one|off  shuffle=on|off
                                              break;
                                  
                                          // browse            
                                          case 'play_preset':    // heos://browse/play_preset?pid=player_id&preset=preset_position
                                              cmd_group = 'browse';
                                              break;
                                          case 'play_stream':    // heos://browse/play_stream?pid=player_id&url=url_path
                                              cmd_group = 'browse';
                                              break;
                                              
                                      }        
                                      return 'heos://'+cmd_group+'/'+cmd+'?pid=' + this.pid + param;
                                  }
                                  
                                  /** Nachricht (command) an player senden
                                      es sind auch mehrere commands, getrennt mit | erlaubt
                                      bsp: set_volume&level=20|play_preset&preset=1
                                   **/
                                  sendCommand (command) {
                                      this.setState('last_error', '');
                                      var cmds = command.split('|');
                                      for (var c=0; c<cmds.length; c++) {
                                          this.heos.msgs.push( this.commandToMsg(cmds[c]) );
                                      }
                                      this.heos.sendNextMsg();
                                  }
                                  
                                  
                                  } // end of HeosPlayer
                                  
                                  
                                  /* -----
                                     Heos
                                     ----- */
                                  // Heos Instanz erzeugen und verbinden   
                                  var heos = new Heos( );
                                  heos.connect();
                                  
                                  // wenn das Script beendet wird, dann auch die Heos Instanz beenden
                                  onStop(function () { 
                                      heos.disconnect(); 
                                  }, 0 );
                                  
                                  
                                  

                                  Ist die Version von Uhula und läuft. Manchmal klappt bei mir der Login nicht, ich habe mir eine Checkbox in vis angelegt und schalte das Script dann kurz aus/ an.

                                  Grüße

                                  Brati

                                  CCU2 - 46 Geräte, ioBroker auf Intel NUC (DN2820FYKH) mit Tab als Frontend, Projekt Gartenhaus mit HM

                                  1 Antwort Letzte Antwort
                                  0
                                  • Hollywood82H Offline
                                    Hollywood82H Offline
                                    Hollywood82
                                    schrieb am zuletzt editiert von
                                    #28

                                    Hallo , vielleicht kann mir einer bei dem Heos Script helfen. Ich nutze iobroker auf nem Raspberry pi3 und habe jetzt das Script aus dem letzten Spoiler hinzugefügt. Er zeigt mir immer einen Error an, wenn er zu der IP(vom Raspberry) und Port 1255 eine Verbindung aufbauen will. Bin noch recht neu hier...

                                     

                                    javascript.0 2019-04-30 20:34:31.357 info script.js.common.Heos: [Heos] disconnected from HEOS
                                    javascript.0 2019-04-30 20:34:31.355 info script.js.common.Heos: [Heos] disconnecting from HEOS ...
                                    javascript.0 2019-04-30 20:34:31.354 error script.js.common.Heos: [Heos] Error: connect ECONNREFUSED 192.168.2.38:1255
                                    javascript.0 2019-04-30 20:34:31.334 info script.js.common.Heos: [Heos] connecting to 192.168.2.38 ...
                                    javascript.0 2019-04-30 20:34:30.880 info script.js.common.Heos: registered 1 subscription and 0 schedules
                                    javascript.0 2019-04-30 20:34:30.607 info Start javascript script.js.common.Heos

                                    B 1 Antwort Letzte Antwort
                                    0
                                    • Hollywood82H Hollywood82

                                      Hallo , vielleicht kann mir einer bei dem Heos Script helfen. Ich nutze iobroker auf nem Raspberry pi3 und habe jetzt das Script aus dem letzten Spoiler hinzugefügt. Er zeigt mir immer einen Error an, wenn er zu der IP(vom Raspberry) und Port 1255 eine Verbindung aufbauen will. Bin noch recht neu hier...

                                       

                                      javascript.0 2019-04-30 20:34:31.357 info script.js.common.Heos: [Heos] disconnected from HEOS
                                      javascript.0 2019-04-30 20:34:31.355 info script.js.common.Heos: [Heos] disconnecting from HEOS ...
                                      javascript.0 2019-04-30 20:34:31.354 error script.js.common.Heos: [Heos] Error: connect ECONNREFUSED 192.168.2.38:1255
                                      javascript.0 2019-04-30 20:34:31.334 info script.js.common.Heos: [Heos] connecting to 192.168.2.38 ...
                                      javascript.0 2019-04-30 20:34:30.880 info script.js.common.Heos: registered 1 subscription and 0 schedules
                                      javascript.0 2019-04-30 20:34:30.607 info Start javascript script.js.common.Heos

                                      B Offline
                                      B Offline
                                      Brati
                                      schrieb am zuletzt editiert von Brati
                                      #29

                                      @Hollywood82

                                      Ist bei dir die JS Instanz richtig konfiguriert?

                                      Zwischenablage01.jpg

                                      Dort muss node-ssdp eingetragen werden...

                                      Grüße

                                      Brati

                                      CCU2 - 46 Geräte, ioBroker auf Intel NUC (DN2820FYKH) mit Tab als Frontend, Projekt Gartenhaus mit HM

                                      1 Antwort Letzte Antwort
                                      0
                                      • Hollywood82H Offline
                                        Hollywood82H Offline
                                        Hollywood82
                                        schrieb am zuletzt editiert von
                                        #30

                                        Danke @Brati
                                        Probiere ich heute Abend aus.

                                        VG

                                        1 Antwort Letzte Antwort
                                        0
                                        • Hollywood82H Offline
                                          Hollywood82H Offline
                                          Hollywood82
                                          schrieb am zuletzt editiert von
                                          #31

                                          Leider keine Änderung, versucht sich immer noch mit dem Raspberry zu verbinden und nicht im Netzwerk nach den HEOS Geräten zu suchen...

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


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          595

                                          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